package com.douqu.game.main.msg;

import com.bean.core.util.Utils;
import com.douqu.game.core.config.*;
import com.douqu.game.core.config.challenge.*;
import com.douqu.game.core.config.common.CommonData;
import com.douqu.game.core.config.common.GoodsData;
import com.douqu.game.core.config.drop.DropGroupConfig;
import com.douqu.game.core.controller.PlayerController;
import com.douqu.game.core.database.model.PlayerModel;
import com.douqu.game.core.e.*;
import com.douqu.game.core.entity.Player;
import com.douqu.game.core.entity.battle.BattleDetail;
import com.douqu.game.core.entity.battle.BattleInitParam;
import com.douqu.game.core.entity.battle.BattleInitParamInstance;
import com.douqu.game.core.entity.common.TwoTuple;
import com.douqu.game.core.entity.db.*;
import com.douqu.game.core.entity.ext.BagInfo;
import com.douqu.game.core.entity.ext.ChallengeInfo;
import com.douqu.game.core.entity.ext.MailInfo;
import com.douqu.game.core.entity.ext.TaskInfo;
import com.douqu.game.core.entity.ext.data.boon.FlashSaleRecord;
import com.douqu.game.core.entity.ext.data.challenge.*;
import com.douqu.game.core.entity.ext.data.major.TalentBean;
import com.douqu.game.core.entity.world.*;
import com.douqu.game.core.factory.*;
import com.douqu.game.core.protobuf.SGChallengeProto;
import com.douqu.game.core.protobuf.SGChallengeProto.*;
import com.douqu.game.core.protobuf.SGCommonProto;
import com.douqu.game.core.protobuf.SGMainProto;
import com.douqu.game.core.protobuf.SGPlayerProto;
import com.douqu.game.core.util.*;
import com.douqu.game.main.GameServer;
import com.douqu.game.main.msg.param.RequestParam;
import com.douqu.game.main.server.RecordManager;
import com.douqu.game.main.server.entity.NoticeInfo;
import com.douqu.game.main.service.PlayerService;
import com.douqu.game.main.service.WorldService;
import com.douqu.game.main.util.MsgUtils;
import com.google.protobuf.InvalidProtocolBufferException;
import com.douqu.game.core.util.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import java.text.MessageFormat;
import java.text.ParseException;
import java.util.*;

/**
 * @author wangzhenfei 2017-08-21 10:06 挑战消息（副本，竞技场，官阶战）
 */
@Component
public class ChallengeMsgChannel implements AMsgChannel {
	@Autowired
	private PlayerService playerService;

	@Autowired
	private WorldService worldService;

	@Override
	public void messageChannel(int code, PlayerController playerController, byte[] data) throws Exception {
		// 获取相应的数据
		if (playerController == null)
			throw new Exception("playerController is null");

		switch (code) {
		/***************************** 副本 ***********************/
		case SGMainProto.E_MSG_ID.MsgID_Instance_GetInstanceInfo_VALUE:
			getInstanceList(playerController, data);
			break;
		case SGMainProto.E_MSG_ID.MsgID_Instance_PassLevel_VALUE:
			addPassLevel(playerController, data);
			break;
		case SGMainProto.E_MSG_ID.MsgID_Instance_ReceiveAward_VALUE:
			receiveAward(playerController, data);
			break;
//		case SGMainProto.E_MSG_ID.MsgID_Instance_RequestLevelBattle_VALUE:
//			int chapterId = 101;
//			int levelId = 10101;
//			int supportCardId = 0;
//			requestLevelBattle(playerController, chapterId,levelId,supportCardId);
//		break;
		case SGMainProto.E_MSG_ID.MsgID_Instance_ReceiveLevelBoxReward_VALUE:
			receiveLevelAward(playerController, data);
			break;
		case SGMainProto.E_MSG_ID.MsgID_Instance_GetLastPassLevel_VALUE:
			getLastPassLevel(playerController);
			break;
		case SGMainProto.E_MSG_ID.MsgID_Instance_CarbonSelectInit_VALUE:
			carbonSelectInit(playerController);
			break;
		/***************************** 竞技场 ***********************/
		case SGMainProto.E_MSG_ID.MsgID_Arena_GetArenaInfo_VALUE:
			getPlayerArenaRankInfo(playerController, data);
			break;
		case SGMainProto.E_MSG_ID.MsgID_Arena_Challenge_VALUE:
			arenaChallenge(playerController, data);
			break;
		case SGMainProto.E_MSG_ID.MsgID_Arena_GetDailyReward_VALUE:
			getDailyReward(playerController);
			break;
		case SGMainProto.E_MSG_ID.MsgID_Arena_PreviewRank_VALUE:
			previewRank(playerController);
			break;
		case SGMainProto.E_MSG_ID.MsgID_Arena_RewardRecord_VALUE:
			rewardRecord(playerController);
			break;
		case SGMainProto.E_MSG_ID.MsgID_Arena_ExchangeReward_VALUE:
			exchangeReward(playerController, data);
			break;
		case SGMainProto.E_MSG_ID.MsgID_Arena_Sweep_VALUE:
			sweepArena(playerController, data);
			break;
		/***************************** 官阶战 ***********************/
		case SGMainProto.E_MSG_ID.MsgID_OfficialWar_InitInfo_VALUE:
			initInfo(playerController, data, code);
			break;
		case SGMainProto.E_MSG_ID.MsgID_OfficialWar_PreviewRank_VALUE:
			previewRank(playerController, data, code);
			break;
		case SGMainProto.E_MSG_ID.MsgID_OfficialWar_ChallengeRank_VALUE:
			challengeRank(playerController, data, code);
			break;
		case SGMainProto.E_MSG_ID.MsgID_OfficialWar_SweepRank_VALUE:
			sweepRank(playerController, data, code);
			break;
		case SGMainProto.E_MSG_ID.MsgID_OfficialWar_GetDailyReward_VALUE:
			getDailyReward(playerController, data, code);
			break;
		case SGMainProto.E_MSG_ID.MsgID_OfficialWar_ExchangeReward_VALUE:
			exchangeReward(playerController, data, code);
			break;
		case SGMainProto.E_MSG_ID.MsgID_OfficialWar_RewardRecord_VALUE:
			rewardRecord(playerController, data, code);
			break;
		case SGMainProto.E_MSG_ID.MsgID_OfficialWar_IntegralReward_VALUE:
			integralReward(playerController, data, code);
			break;
		case SGMainProto.E_MSG_ID.MsgID_OfficialWar_IntegralRewardRecord_VALUE:
			integralRewardRecord(playerController, data, code);
			break;
		/***************************** 英雄圣殿 ***********************/
		case SGMainProto.E_MSG_ID.MsgID_HeroTemple_InitInfo_VALUE:
			heroTempleInitInfo(playerController, data, code);
			break;
		case SGMainProto.E_MSG_ID.MsgID_HeroTemple_Challenge_VALUE:
			heroTempleChallenge(playerController, data, code);
			break;
		case SGMainProto.E_MSG_ID.MsgID_HeroTemple_Sweep_VALUE:
			heroTempleSweep(playerController, data, code);
			break;
		/***************************** 远征副本 ***********************/
		case SGMainProto.E_MSG_ID.MsgID_Expedition_Init_VALUE:
			expeditionInit(playerController, data, code);
			break;
		case SGMainProto.E_MSG_ID.MsgID_Expedition_ChallengeRequest_VALUE:
			expeditionChallengeRequest(playerController, data, code);
			break;
		case SGMainProto.E_MSG_ID.MsgID_Expedition_FreshBoss_VALUE:
			expeditionFreshBoss(playerController, data, code);
			break;
		case SGMainProto.E_MSG_ID.MsgID_Expedition_CallBoss_VALUE:
			expeditionCallBoss(playerController, data, code);
			break;
		case SGMainProto.E_MSG_ID.MsgID_MoppingUp_CallBoss_VALUE:
			moppingUp(playerController, data, code);
			break;
			/***************************** Boss ***********************/
		case SGMainProto.E_MSG_ID.MsgID_WorldBossInit_VALUE:
			worldBossInit(playerController, data, code);
			break;
		default:
			break;

		}

		// if(CodeFactory.TEST){
		// /**
		// * 暂时的保存任务，调试完毕需要删除
		// */
		// worldService.update(GameServer.getInstance().getWorldManager().getWorldInfo());
		// }
	}

	/**
	 * boss战初始化
	 *
	 * @param playerController
	 * @param data
	 * @param code
	 */
	private void worldBossInit(PlayerController playerController, byte[] data, int code) {
		S2C_WorldBossInit.Builder response = S2C_WorldBossInit.newBuilder();
		WorldBossData worldBossData = WorldInfoFactory.getInstance().getWorldBossData();
		if (worldBossData.isBossActive()) {
			response.setCurrentBossId(Integer.valueOf(worldBossData.getBossInfo().getIndexInfo()));
			response.setCurrentBossHp(worldBossData.getBossInfo().getCurrentTotalHp());
			response.setCurrentBossMaxHp(worldBossData.getBossInfo().getMaxTotalHp());
			response.setBossCountDown(worldBossData.getBossCountDown());
		} else {
			response.setCurrentBossId(worldBossData.getNextBossId(GameServer.startTime));
		}
		response.addAllKillBossIds(worldBossData.getHasKillBossIntValue());
		BossData bossData = playerController.getPlayer().getBossData();
		response.setMaxChallengeTimes(bossData.getTodayTotalChallengeTimes());
		response.setRemainChallengeTimes(bossData.getRemainChallengeTimes());
		response.setWeekNum(CoreUtils.getWeek());
		response.addAllEndBossIds(CoreUtils.getEndBossList(worldBossData.getHasKillBossIntValue(),worldBossData.getBossInfo()));
		LogUtils.debug("返回boss战斗初始化信息:" + response);
		playerController.sendMsg(code, response.build().toByteArray());
	}

	/**
	 * boss战斗返回
	 *
	 * @param playerController
	 * @param battleDetail
	 * @param isKillBoss
	 */
	public void worldBossBattleEnd(PlayerController playerController, String bossId, BattleDetail battleDetail, boolean isKillBoss, GoodsData[] reward, int exploit, String exploitType)
	{
		LogUtils.debug("boss战斗返回bossId:" + bossId + ", isKillBoss:" + isKillBoss);
		WorldBossData worldBossData = WorldInfoFactory.getInstance().getWorldBossData();
		long damage = battleDetail.getTeam1Info().getTotalDamage();
		//伤害直接统计到排行榜上
		//worldBossData.addChallengeRecord(playerController.getObjectIndex(), bossId, damage);
		WorldRankData rankData = WorldInfoFactory.getInstance().getWorldRankData();
		//有伤害才上排行
		if (damage > 0){
			rankData.updateRankInfo(SGCommonProto.E_RANK_TYPE.RANK_TYPE_BOSS,playerController.getObjectIndex(),damage);
		}
		if (isKillBoss) {
			if (worldBossData.killBoss(bossId)){
				RecordManager.getInstance().addBossBattle(playerController.getPlayer(), bossId, "0", damage, exploit, exploitType);
				boosDeath(playerController, bossId);
			}else
				LogUtils.info("boss already kill by other bossId ->" + bossId);
		} else if (battleDetail != null) {
			if (worldBossData.freshBossHp(battleDetail.getTeam2Info())){
				//返回true 表示boss死亡
				boosDeath(playerController,bossId);
			}
			RecordManager.getInstance().addBossBattle(playerController.getPlayer(), bossId, battleDetail.getTeam2Info().getHpInfo(), damage, exploit, exploitType);
		}
		// int count = worldBossData.calculateDamageRate(battleTemp);
		// StableDataConfig stableDataConfig =
		// DataFactory.getInstance().getGameObject(DataFactory.STABLE_DATA_KEY,
		// E_StableDataType.BOSS_CHALLENGE_PRODUCT.getCode());
		// if(stableDataConfig != null){
		// playerController.getPlayerResult().getBagInfo().addGoods(new GoodsData[]{new
		// GoodsData(stableDataConfig.goods[0].type,
		// stableDataConfig.goods[0].id, count)}, null);
		// }else {
		// LogUtils.debug("StableDataConfig id error : " +
		// E_StableDataType.BOSS_CHALLENGE_PRODUCT.getCode());
		// }
		// WorldBossConfig config =
		// DataFactory.getInstance().getGameObject(DataFactory.WORLD_BOSS_KEY,
		// Integer.valueOf(bossId));
		// playerController.getPlayerResult().getBagInfo().addGoods(config.passReward,
		// null);
		playerController.getPlayer().getBagInfo().addGoods(reward, null);
		playerController.getPlayer().getBossData().addChallengeTimes();

		playerController.getPlayer().getSevenDayData().checkAllRewardState(SevenDayFactory.EVENT_TYPE_26,1);
	}

	/**
	 * boss死亡 通知拍卖行
	 * 播放走马灯
	 */
	private void boosDeath(PlayerController playerController,String bossId){

		WorldBossConfig config = DataFactory.getInstance().getGameObject(DataFactory.WORLD_BOSS_KEY,Integer.valueOf(bossId));
		if (config == null){
			LogUtils.error("bossConfig is null ->" + bossId);
			return;
		}
		GameServer.getInstance().getWorldManager()
				.addNotice(new NoticeInfo(WordFactory.getWord(WordFactory.BOSS_DEATH_NOTICE,playerController.getName(),config.name),
						5, 10, "system", DataFactory.currentTime,E_NoticeType.NOTICE_TYPE_BOSS));

		WorldBossConfig bossConfig = DataFactory.getInstance().getGameObject(DataFactory.WORLD_BOSS_KEY, Integer.valueOf(bossId));
		List<Integer> ids = bossConfig.getAuctionIds();
		WorldAuctionData auctionData = WorldInfoFactory.getInstance().getWorldAuctionData();
		List<String> objectIndex = new ArrayList<>();
		List<WorldRankBean> rankList = WorldInfoFactory.getInstance().getWorldRankData().getRankList(SGCommonProto.E_RANK_TYPE.RANK_TYPE_BOSS);
		for(WorldRankBean index : rankList){
			objectIndex.add(index.getObjectIndex());
		}
		LogUtils.debug("添加到拍卖行 ids:" + ids );
		for(Integer id : ids){
			auctionData.newAuction(id, objectIndex, E_AuctionSource.AUCTION_SOURCE_BOSS.getCode());
		}

		//玩家击杀boss发放邮件击杀奖励
		MailConfig mailConfig = DataFactory.getInstance().getGameObject(DataFactory.MAIL_MODEL_KEY,E_MailModelType.BOSS_KILL_REWARD.getCode());
		List<GoodsData> attachList = new ArrayList<>();
		attachList.addAll(Arrays.asList(bossConfig.passReward));
		MailDB mailDB = new MailDB(mailConfig.title, MessageFormat.format
				(mailConfig.content,bossConfig.masterName,BoonMsgChannel.getGoodName(attachList.get(0).type,attachList.get(0).id)),attachList);
		MailInfo mailInfo = playerController.getPlayer().getExtInfo(MailInfo.class);
		mailInfo.addMail(SGCommonProto.E_MAIL_TYPE.MAIL_TYPE_SYSTEM_VALUE,mailDB);
	}
	/*************************************
	 * 副本star
	 *************************************/

	/**
	 * 获取关卡的宝箱奖励
	 *
	 * @param playerController
	 * @param data
	 */
	private void receiveLevelAward(PlayerController playerController, byte[] data) {
		SGChallengeProto.S2C_ReceiveLevelBoxReward.Builder response = SGChallengeProto.S2C_ReceiveLevelBoxReward
				.newBuilder();
		SGChallengeProto.C2S_ReceiveLevelBoxReward request = null;
		try {
			request = SGChallengeProto.C2S_ReceiveLevelBoxReward.parseFrom(data);
		} catch (InvalidProtocolBufferException e) {
			// e.printStackTrace();
			LogUtils.error(
					"领取宝箱参数错误 -> " + playerController.getName() + " data len:" + (data == null ? 0 : data.length));
		}
		if (request == null) {
			playerController.sendWarn(WordFactory.PARAM_ERROR);
			return;
		}
		int mapId = request.getChapterId();
		int levelId = request.getLevelId();

		InstanceData instanceInfo = playerController.getPlayer().getInstanceData();
		LogUtils.debug("领取关卡宝箱请求参数-->地图id : " + mapId);
		LogUtils.debug("领取关卡宝箱请求参数-->关卡id : " + levelId);
		// 判断mapid和levelid是否合法
		InstanceConfig instanceConfig = DataFactory.getInstance().getGameObject(DataFactory.INSTANCE_KEY, mapId);
		if (instanceConfig == null) {
			LogUtils.debug("领取关卡宝箱配置错误结果 ： " + mapId);
			playerController.sendWarn(WordFactory.PARAM_ERROR);
			return;
		}

		// 判断该关卡是否有奖励
		LevelConfig configLLevelConfig = DataFactory.getInstance().getGameObject(DataFactory.LEVEL_KEY, levelId);
		if (configLLevelConfig == null || configLLevelConfig.boxReward == 0) {
			// 返回给客户端
			LogUtils.debug("领取关卡宝箱结果 ： " + "该关卡没有宝箱可以领取");
			playerController.sendWarn(WordFactory.BOX_NOTHING_REWARD);
			return;
		}

		InstanceListDB instanceList = instanceInfo.getInstanceList(instanceConfig.type);
		InstanceDB instanceConfigMap;
		if (instanceList == null || (instanceConfigMap = instanceList.getInstanceMap(mapId)) == null) {
			LogUtils.debug("领取关卡宝箱结果 ： " + "地图未解锁");
			// 返回给客户端
			playerController.sendWarn(WordFactory.MAP_NOT_UNLOCK);
			return;
		}

		LevelDB lvDB = instanceConfigMap.getLevelMap().get(levelId);

		if (lvDB == null) {// 未解锁
			LogUtils.debug("领取关卡宝箱结果 ： " + "地图未解锁");
			// 返回给客户端
			playerController.sendWarn(WordFactory.MAP_NOT_UNLOCK);
			return;
		}

		if (lvDB.isReceive()) {
			LogUtils.debug("领取关卡宝箱结果 ： " + "已经领取过了");
			// 返回给客户端
			playerController.sendWarn(WordFactory.GET_REWARD_ED);
			return;
		}

		lvDB.setReceive(true);

		DropGroupConfig dropGroupConfig = DataFactory.getInstance().getGameObject(DataFactory.DROP_GROUP_KEY,
				configLLevelConfig.boxReward);
		if (dropGroupConfig != null)
			dropGroupConfig.reward(playerController);
		// 返回给客户端
		playerController.sendMsg(SGMainProto.E_MSG_ID.MsgID_Instance_ReceiveLevelBoxReward_VALUE,
				response.build().toByteArray());

	}

	/**
	 * 获取副本宝箱奖励
	 *
	 * @param playerController
	 * @param data
	 */
	private void receiveAward(PlayerController playerController, byte[] data) {

		SGChallengeProto.C2S_ReceiveInstanceAward request = null;
		try {
			request = SGChallengeProto.C2S_ReceiveInstanceAward.parseFrom(data);
		} catch (InvalidProtocolBufferException e) {
			e.printStackTrace();
		}
		if (request == null) {
			playerController.sendWarn(WordFactory.PARAM_ERROR);
			return;
		}
		int mapId = request.getChapterId();
		int id = request.getRewardId();// 领取的ID
		LogUtils.debug("领取奖励请求参数--->mapId:" + mapId);
		LogUtils.debug("领取奖励请求参数--->rewardId:" + id);
		InstanceConfig instanceConfig = DataFactory.getInstance().getGameObject(DataFactory.INSTANCE_KEY, mapId);
		if (instanceConfig == null) {
			playerController.sendWarn(WordFactory.PARAM_ERROR);
			return;
		}

		InstanceStarBox starBox = instanceConfig.getInstanceStarBox(id);
		if (starBox == null) {
			LogUtils.debug("不存在宝箱id--->" + id);
			playerController.sendWarn(WordFactory.PARAM_ERROR);
			return;
		}

		InstanceListDB instanceList = playerController.getPlayer().getInstanceData()
				.getInstanceList(instanceConfig.type);
		InstanceDB instanceConfigMap = null;
		if (instanceList == null || (instanceConfigMap = instanceList.getInstanceMap(mapId)) == null) {
			LogUtils.debug("领取关卡宝箱结果 ： " + "地图未解锁");
			// 返回给客户端
			playerController.sendWarn(WordFactory.MAP_NOT_UNLOCK);
			return;
		}
		if (instanceConfigMap == null) {
			LogUtils.debug("该地图还未解锁");
			// 返回给客户端
			playerController.sendWarn(WordFactory.MAP_NOT_UNLOCK);
			return;
		}
		if (instanceConfigMap.getHasReward().contains(id)) {
			LogUtils.debug("已经领取过本次次奖励");
			// 返回给客户端
			playerController.sendWarn(WordFactory.GET_REWARD_ED);
			return;
		}

		int mapStars = 0;
		for (LevelDB levelConfig : instanceConfigMap.getFinishLevelDbs()) {
			mapStars += CoreUtils.getStarNum(levelConfig.getMaxStars());
		}
		LogUtils.debug("用户总星数：" + mapStars + ", 请求星数： " + starBox.star);
		if (mapStars < starBox.star) {
			LogUtils.debug("星级不满足条件" + mapStars);
			playerController.sendWarn(WordFactory.CONDITION_ERROR);
			return;
		}
		DropGroupConfig dropGroupConfig = DataFactory.getInstance().getGameObject(DataFactory.DROP_GROUP_KEY,
				starBox.dropId);

		dropGroupConfig.reward(playerController);

		instanceConfigMap.getHasReward().add(id);

		SGChallengeProto.S2C_ReceiveInstanceAward.Builder response = SGChallengeProto.S2C_ReceiveInstanceAward
				.newBuilder();

		playerController.sendMsg(SGMainProto.E_MSG_ID.MsgID_Instance_ReceiveAward_VALUE,
				response.build().toByteArray());
	}

	/**
	 * 通过某一关卡
	 *
	 * @param playerController
	 * @param data
	 */
	private void addPassLevel(PlayerController playerController, byte[] data) {

		SGChallengeProto.C2S_PassLevel request = null;
		try {
			request = SGChallengeProto.C2S_PassLevel.parseFrom(data);
		} catch (InvalidProtocolBufferException e) {
			e.printStackTrace();
		}
		if (request == null) {
			playerController.sendWarn(WordFactory.PARAM_ERROR);
			return;
		}

		int mapId = request.getChapterId();
		int levelId = request.getLevelId();
		int stars = request.getStarts();

		InstanceData instanceInfo = playerController.getPlayer().getInstanceData();
		LogUtils.debug("通过副本请求参数-->地图id : " + mapId);
		LogUtils.debug("通过副本请求参数-->关卡id : " + levelId);
		LogUtils.debug("通过副本请求参数-->通过星星数 : " + stars);
		LogUtils.debug("通过副本请求参数-->通过关卡前 ： " + instanceInfo.toString());
		// 判断mapid和levelid是否合法
		InstanceConfig instanceConfig = DataFactory.getInstance().getGameObject(DataFactory.INSTANCE_KEY, mapId);
		if (instanceConfig == null) {
			LogUtils.error("副本id错误");
			playerController.sendWarn(WordFactory.PARAM_ERROR);
			return;
		}

		if (!instanceInfo.canPassLevel(instanceConfig.type, mapId, levelId)) {
			LogUtils.debug("副本过关结果 ： " + "地图未解锁");
			// 返回给客户端
			playerController.sendWarn(WordFactory.MAP_NOT_UNLOCK);
			return;
		}

		if (stars == 0) {
			LogUtils.debug("副本战斗失败");
			// 缓存结算数据，等待客户端重连主服务器获取
			InstanceData.PassLevelCache response = new InstanceData.PassLevelCache(mapId, levelId, stars, false);
			LogUtils.debug("缓存过关数据数据：" + response);
			instanceInfo.responseTemp = response;
		} else {
			if (stars > 7 || stars < 1) {
				// 返回给客户端
				LogUtils.debug("副本过关结果 ： " + "参数异常，星星数不满足条件");
				playerController.sendWarn(WordFactory.PARAM_ERROR);
				return;
			}

			if (!instanceInfo.canPassLevel(instanceConfig.type, mapId, levelId)) {
				LogUtils.debug("当前副本未解锁");
				// 返回给客户端
				playerController.sendWarn(WordFactory.MAP_NOT_UNLOCK);
			}

			boolean firstPass = instanceInfo.addPassLevel(instanceConfig.type, mapId, levelId, stars); // 是否第一次通关
			if (firstPass) {
				// 发送首次通关奖励
				sendFirstPassReward(playerController,
						DataFactory.getInstance().getGameObject(DataFactory.LEVEL_KEY, levelId));
				//检测开服活动是否完成
				playerController.getPlayer().getSevenDayData().checkAllRewardState(SevenDayFactory.EVENT_TYPE_8,instanceInfo.getTotalStart());
			}
			GameServer.getInstance().getWorldManager().updateRankInfo(SGCommonProto.E_RANK_TYPE.RANK_TYPE_INSTANCE,
					playerController.getPlayer(), instanceInfo.getTotalStart());

			if (instanceInfo.hasRedPointRemind()) {
				SendUtils.sendRedPointRemind(playerController, SGCommonProto.E_RED_POINT_TYPE.RED_POINT_TYPE_INSTANCE);
			}
			// 缓存结算数据，等待客户端重连主服务器获取
			InstanceData.PassLevelCache response = new InstanceData.PassLevelCache(mapId, levelId, stars, firstPass);
			LogUtils.debug("缓存过关数据数据：" + response);
			instanceInfo.responseTemp = response;

			// 检测任务是否完成
			TaskInfo taskInfo = playerController.getPlayer().getExtInfo(TaskInfo.class);
			taskInfo.check(TaskFactory.TASK_TARAGET_PASSLEVEL, levelId);
			taskInfo.check(TaskFactory.TASK_TARAGET_EVERYDAY_INSTANCE, 1);

			//检测开服活动是否完成
			playerController.getPlayer().getSevenDayData().checkAllRewardState(SevenDayFactory.EVENT_TYPE_9,1,levelId,instanceConfig.type);


		}
	}

	/**
	 * 发放首次过关奖励
	 *
	 * @param playerController
	 * @param lv
	 */
	private void sendFirstPassReward(PlayerController playerController, LevelConfig lv) {
		BagInfo bagInfo = playerController.getPlayer().getExtInfo(BagInfo.class);
		bagInfo.addGoods(lv.passReward, null);
	}

	/**
	 * 获取最后一次的挑战结果
	 *
	 * @param playerController
	 */
	private void getLastPassLevel(PlayerController playerController) {
		InstanceData instanceInfo = playerController.getPlayer().getInstanceData();
		SGChallengeProto.S2C_GetLastPassLevel.Builder response = SGChallengeProto.S2C_GetLastPassLevel.newBuilder();
		if (instanceInfo.responseTemp != null) {
			response.setChapterId(instanceInfo.responseTemp.mapId);
			response.setLevelId(instanceInfo.responseTemp.levelId);
			response.setStarts(instanceInfo.responseTemp.stars);

			if (instanceInfo.responseTemp.stars > 0 && instanceInfo.responseTemp.firstPass) {
				// 是否弹出通关限时活动
				FlashSaleRecord fsr = playerController.getPlayer().getBonusData().check(playerController,
						E_FlashSaleType.PASS_INSTANCE);
				if (fsr != null) {
					playerController.sendMsg(SGMainProto.E_MSG_ID.MSGID_Player_PushFlashSale_VALUE,
							SGPlayerProto.S2C_PushFlashSale.newBuilder()
									.setSaleObject(SGCommonProto.KeyListObject.newBuilder().setKey(fsr.id)
											.setValue((int) (fsr.endTime - DataFactory.currentTime)))
									.build().toByteArray());
				}
			}
		}
		playerController.sendMsg(SGMainProto.E_MSG_ID.MsgID_Instance_GetLastPassLevel_VALUE,
				response.build().toByteArray());
		LogUtils.debug("返回给客户端最近的挑战信息 ： " + response.toString());
		LogUtils.debug("通过关卡后 ： " + instanceInfo.toString());
	}

	/**
	 * 获取战斗相关的红点与次数信息
	 * @param playerController
	 */
	public void carbonSelectInit(PlayerController playerController){
		S2C_CarbonSelectInit.Builder response = S2C_CarbonSelectInit.newBuilder();
		ChallengeInfo challengeInfo = playerController.getPlayer().getExtInfo(ChallengeInfo.class);
		List<SGCommonProto.E_RED_POINT_TYPE> redList = challengeInfo.checkRedPointRemindAllCondition(DataFactory.currentTime);
		if (redList == null)
			redList = new ArrayList<>();
		response.addAllRedTypes(redList);
		if (redList.contains(SGCommonProto.E_RED_POINT_TYPE.RED_POINT_TYPE_HERO_TEMPLE))
			response.setRemainTimerEquip(challengeInfo.getHeroTempleData().getTodayRemainChallengeTimes());
		if (redList.contains(SGCommonProto.E_RED_POINT_TYPE.RED_POINT_TYPE_OFFICIAL_RANK))
			response.setRemainTimerOfficial(challengeInfo.getOfficialData().getTodayRemainChallengeTimes());
		if (redList.contains(SGCommonProto.E_RED_POINT_TYPE.RED_POINT_TYPE_ARENA))
			response.setRemainTimerArena(challengeInfo.getArenaData().getRemainTodayChallengeTimes());

		TwoTuple<SGCommonProto.E_BOSS_STATE,Integer> twoTuple = WorldInfoFactory.getInstance().getWorldBossData().bossState();
		response.setBossState(twoTuple.getFirst());
		if (twoTuple.getFirst() == SGCommonProto.E_BOSS_STATE.BOSS_STATE_NOT_OPEN){
			response.setNextBossId(twoTuple.getSecond());
		}
		//response.setCurrentServerTime(DataFactory.currentTime);
		playerController.sendMsg(SGMainProto.E_MSG_ID.MsgID_Instance_CarbonSelectInit_VALUE,response.build().toByteArray());
		LogUtils.debug("返回客户端战斗相关红点与次数信息： " + response.toString());
	}

	/**
	 * 请求副本战斗
	 *
	 * @param playerController
	 */
	public void requestLevelBattle(PlayerController playerController, int chapterId, int levelId, int supportCardId) {
		LevelConfig levelConfig = DataFactory.getInstance().getGameObject(DataFactory.LEVEL_KEY, levelId);
		if (levelConfig == null || levelConfig.getInstanceId() != chapterId) {
			LogUtils.error("levelConfig -> " + levelConfig + " mapId -> " + chapterId);
			playerController.sendWarn(WordFactory.PARAM_ERROR);
			return;
		}

		// 此副本需要完成的主线任务是否完成
		TaskInfo taskInfo = playerController.getPlayer().getExtInfo(TaskInfo.class);
		if (levelConfig.taskId > 0 && !taskInfo.finishTasks.contains(levelConfig.taskId)) {
			playerController.sendWarn(WordFactory.MUST_FINISH_TASK);
			return;
		}
		// for(int id : levelConfig.supportCardIds){
		// CardDB cardDB =
		// playerController.getPlayerResult().getBagInfo().getCardData().getCard(supportCardId);
		// if(cardDB != null && cardDB.battle){
		// continue;
		// }
		// supportCardId = id;
		// break;
		// }

		if (supportCardId != 0) {
			if (!levelConfig.isSupportCardIn(supportCardId)) {
				LogUtils.error("支援卡不存在：" + supportCardId);
				playerController.sendWarn(WordFactory.PARAM_ERROR);
				return;
			}
			CardDB cardDB = playerController.getPlayer().getBagInfo().getCardData().getCard(supportCardId);

			if (cardDB != null && cardDB.battle) {
				supportCardId = 0;
			}
		}

		InstanceConfig config = DataFactory.getInstance().getGameObject(DataFactory.INSTANCE_KEY, chapterId);
		if (playerController.getPlayer().getLv() < config.unLockLv) {
			LogUtils.error("副本挑战等级未达到 需要等级: " + config.unLockLv);
			playerController.sendWarn(WordFactory.MAP_UNLOCK_LV_NOT_TOUCH);
			return;
		}

		InstanceData instanceInfo = playerController.getPlayer().getInstanceData();
		if (!instanceInfo.canPassLevel(config.type, chapterId, levelId)) {
			LogUtils.debug("当前副本未解锁");
			// 返回给客户端
			playerController.sendWarn(WordFactory.MAP_NOT_UNLOCK);
		}

		if (config.type == E_InstanceType.LEVEL_2.getCode()) {
			String message = CoreUtils.checkFunctionOpen(FunctionFactory.UNLOCK_ELITIST_COPY, playerController.getPlayer());
			if (message != null){
				FunctionConfig functionConfig = DataFactory.getInstance().getGameObject(DataFactory.FUNCTION_KEY,
						FunctionFactory.UNLOCK_ELITIST_COPY);
				LogUtils.error(message);
				playerController.sendWarn(WordFactory.UNLOCK_NIGHTMARE_COPY, functionConfig.lv);
				return;
			}
		}
		if (config.type == E_InstanceType.LEVEL_3.getCode()) {
			String message = CoreUtils.checkFunctionOpen(FunctionFactory.UNLOCK_NIGHTMARE_COPY, playerController.getPlayer());
			if (message != null){
				FunctionConfig functionConfig = DataFactory.getInstance().getGameObject(DataFactory.FUNCTION_KEY,
						FunctionFactory.UNLOCK_NIGHTMARE_COPY);
				LogUtils.error(message);
				playerController.sendWarn(WordFactory.UNLOCK_ELITIST_COPY, functionConfig.lv);
				return;
			}
		}

		// startBattle之前检测战斗中的卡牌数量
		String rs = MsgUtils.checkBattleCardCount(playerController.getPlayer());
		if (!com.douqu.game.core.util.StringUtils.isNullOrEmpty(rs)) {
			playerController.sendWarn(rs);
			return;
		}

		MsgUtils.startBattle(playerController, SGCommonProto.E_BATTLE_TYPE.BATTLE_TYPE_INSTANCE,
				E_BattleDetailType.PVE_INSTANCE,
				levelConfig.id + ConstantFactory.UNDERLINE + supportCardId + ConstantFactory.UNDERLINE
						+ levelConfig.cardParamId,
				new BattleInitParamInstance(levelConfig.mapId, levelId), new RequestParam(RequestParam.PARAM_LEVEL_ID, levelConfig.id),
				new RequestParam(RequestParam.PARAM_INSTANCE_ID, levelConfig.getInstanceId()));

	}

	/**
	 * 获取过关列表信息
	 *
	 * @param playerController
	 * @param data
	 */
	private void getInstanceList(PlayerController playerController, byte[] data) {

		SGChallengeProto.S2C_GetInstanceInfo.Builder response = SGChallengeProto.S2C_GetInstanceInfo.newBuilder();
		SGChallengeProto.C2S_GetInstanceInfo request = null;
		try {
			request = SGChallengeProto.C2S_GetInstanceInfo.parseFrom(data);
		} catch (InvalidProtocolBufferException e) {
			e.printStackTrace();
		}
		if (request == null) {
			playerController.sendWarn(WordFactory.PARAM_ERROR);
			return;
		}

		SGCommonProto.E_INSTANCE_TYPE instanceType = request.getInstanceType();
		LogUtils.debug("获取关卡列表信息传入参数 ： " + " 地图类型：" + instanceType);
		InstanceData instanceData = playerController.getPlayer().getInstanceData();

		if (instanceType == null || instanceType == SGCommonProto.E_INSTANCE_TYPE.INSTANCE_TYPE_UNKNOW) {
			SGCommonProto.InstanceList.Builder instanceList = null;
			for (Map.Entry<Integer, InstanceListDB> entry : instanceData.getInstanceListMap().entrySet()) {
				instanceList = SGCommonProto.InstanceList.newBuilder();
				instanceList.setInstanceTypeValue(entry.getKey());
				instanceList.addAllInstances(entry.getValue().getPropInstanceMap());
				response.addInstanceList(instanceList);
			}
		} else {
			InstanceListDB instanceListDB = instanceData.getInstanceList(instanceType.getNumber());
			if (instanceListDB != null) {
				response.addInstanceList(SGCommonProto.InstanceList.newBuilder().setInstanceType(instanceType)
						.addAllInstances(instanceListDB.getPropInstanceMap()));
			}

		}

		LogUtils.debug("返回给客户端关卡列表信息 ： " + response.toString());
		// 返回给客户端
		playerController.sendMsg(SGMainProto.E_MSG_ID.MsgID_Instance_GetInstanceInfo_VALUE,
				response.build().toByteArray());
	}

	/*************************************
	 * 副本end
	 ***********************************************************************************/

	/*************************************
	 * 竞技场star
	 ***********************************************************************************/

	/**
	 * 扫荡竞技场
	 *
	 * @param playerController
	 * @param data
	 */
	private void sweepArena(PlayerController playerController, byte[] data) {
		C2S_ArenaSweep request = null;
		try {
			request = C2S_ArenaSweep.parseFrom(data);
		} catch (InvalidProtocolBufferException e) {
			e.printStackTrace();
		}
		if (request == null) {
			playerController.sendWarn(WordFactory.PARAM_ERROR);
			return;
		}

		ArenaData arenaData = playerController.getPlayer().getArenaData();
		LogUtils.debug("当前已经挑战的挑战次数剩余 :" + arenaData.getRemainTodayChallengeTimes());
		if (!arenaData.isChallengeTimesEnough()) {
			// TODO 挑战次数已经用完
			LogUtils.debug("挑战次数已经用完,当前挑战次数剩余 :" + arenaData.getRemainTodayChallengeTimes());
			playerController.sendWarn(WordFactory.ARENA_TIMES_NOT_ENOUGH);
			return;
		}

		int targetRank = request.getTargetRank();
		int myRank = GameServer.getInstance().getWorldArenaData()
				.getArenaRankByObjectIndex(playerController.getObjectIndex());
		LogUtils.debug("sweepArena， myRank: " + myRank + ", targetRank: " + targetRank);
		if (myRank >= targetRank) { // 自己的排名比目标高
			LogUtils.debug("扫荡失败，自己的排名比目标低");
			playerController.sendWarn(WordFactory.ARENA_NOT_SWEEP_HEIGHT_PLAYER);
			return;
		}
		arenaData.addChallengeTimes(DataFactory.currentTime);
		// 发放扫荡奖励
		StableDataConfig stableDataConfig = DataFactory.getInstance().getGameObject(DataFactory.STABLE_DATA_KEY,
				E_StableDataType.ARENA_PASS_REWARD.getCode());
		BagInfo bagInfo = playerController.getPlayer().getExtInfo(BagInfo.class);
		bagInfo.addGoods(stableDataConfig.goods, null);
		S2C_ArenaSweep.Builder response = S2C_ArenaSweep.newBuilder();
		LogUtils.debug("返回给客户端竞技场扫荡信息 ： " + response.toString());

		// 检测任务是否完成
		playerController.getPlayer().getExtInfo(TaskInfo.class).check(TaskFactory.TASK_TARAGET_MAIN_ARENA_BATTLE, 1);

        // 扫荡要增加竞技场胜利次数
        arenaData.winBattle();

		// 检测任务是否完成
		playerController.getPlayer().getExtInfo(TaskInfo.class).check(TaskFactory.TASK_TARAGET_ARENA, 1);

		//检测开服活动是否完成
		playerController.getPlayer().getSevenDayData().checkAllRewardState(SevenDayFactory.EVENT_TYPE_14,1);


		// 返回给客户端
		playerController.sendMsg(SGMainProto.E_MSG_ID.MsgID_Arena_Sweep_VALUE, response.build().toByteArray());

	}

	/**
	 * 兑换奖励
	 *
	 * @param playerController
	 */
	private void exchangeReward(PlayerController playerController, byte[] data) {
		C2S_ArenaExchangeReward request = null;
		try {
			request = C2S_ArenaExchangeReward.parseFrom(data);
		} catch (InvalidProtocolBufferException e) {
			e.printStackTrace();
		}
		if (request == null) {
			playerController.sendWarn(WordFactory.PARAM_ERROR);
			return;
		}
		ArenaData arenaData = playerController.getPlayer().getArenaData();
		int rewardId = request.getRewardId();
		if (arenaData.getAlreadyRewardIds().contains(rewardId)) {
			LogUtils.debug("竞技场该资源已经兑换过了");
			playerController.sendWarn(WordFactory.ARENA_REWARD_GROUP_ALREADY_REWARD);
			return;
		}
		ExchangeRewardConfig rewardConfig = DataFactory.getInstance().getGameObject(DataFactory.REWARD_KEY, rewardId);
		if (rewardConfig == null || rewardConfig.type != E_ExchangeRewardType.ARENA.getCode()) {
			LogUtils.debug("竞技场兑换 rewardId 不存在：" + rewardId);
			playerController.sendWarn(WordFactory.PARAM_ERROR);
			return;
		}
		int myRank = GameServer.getInstance().getWorldArenaData().getArenaRankByObjectIndex(playerController.getPlayer());
		if (myRank > rewardConfig.minRank || myRank == 0) { // 自己的排名大于要求的最低排名，不符合领取条件
			// TODO error
			LogUtils.debug("竞技场自己的排名大于要求的最低排名，不符合领取条件 ");
			playerController.sendWarn(WordFactory.ARENA_RANK_NOT_ENOUGH);
			return;
		}
		BagInfo bagInfo = playerController.getPlayer().getExtInfo(BagInfo.class);
		// 循环配置表检测自己的资源是否足够
		for (CommonData assets : rewardConfig.needAssets) {
			if (bagInfo.getAsset(assets.id) < assets.value) {// 自己拥有的小于配置的
				// TODO 资源不足
				// 需要的资源不够
				LogUtils.debug("竞技场兑换奖励资源不足 ");
				playerController.sendWarn(WordFactory.ASSET_NOT_ENOUGH, assets.id);
				return;
			}
		}
		arenaData.getAlreadyRewardIds().add(rewardId);
		GoodsData[] consumeData = new GoodsData[rewardConfig.needAssets.length];
		for (int i = 0; i < rewardConfig.needAssets.length; i++) {
			consumeData[i] = new GoodsData(SGCommonProto.E_GOODS_TYPE.GOODS_TYPE_ASSETS_VALUE,
					rewardConfig.needAssets[i].id, rewardConfig.needAssets[i].value);
		}
		bagInfo.addGoods(rewardConfig.reward, consumeData);
		// bagInfo.reduceAsset(rewardConfig.needAssets);
		for (GoodsData goodsData : rewardConfig.reward) {
			addRewardRecord(arenaData, goodsData);
		}

		S2C_ArenaExchangeReward.Builder response = S2C_ArenaExchangeReward.newBuilder();
		LogUtils.debug("返回给客户端竞技场兑换结果 ： " + response.toString());
		// 返回给客户端
		playerController.sendMsg(SGMainProto.E_MSG_ID.MsgID_Arena_ExchangeReward_VALUE, response.build().toByteArray());

	}

	/**
	 * 竞技场兑换记录
	 *
	 * @param playerController
	 */
	private void rewardRecord(PlayerController playerController) {
		S2C_ArenaRewardRecord.Builder response = S2C_ArenaRewardRecord.newBuilder();

		ArenaData arenaData = playerController.getPlayer().getArenaData();
		List<ArenaRewardRecordDB> records = arenaData.getRewardRecords();
		for (ArenaRewardRecordDB record : records) {
			SGCommonProto.RewardInfo.Builder info = SGCommonProto.RewardInfo.newBuilder();
			info.setId(record.getId());
			info.setNum(record.getNum());
			info.setType(SGCommonProto.E_GOODS_TYPE.forNumber(record.getType()));
			response.addRewardInfo(info);
		}

		List<Integer> ids = arenaData.getAlreadyRewardIds();
		for (Integer id : ids) {
			response.addAlreadyRewardIds(id);
		}

		LogUtils.debug("返回给客户端竞技场兑换记录 ： " + response.toString());
		// 返回给客户端
		playerController.sendMsg(SGMainProto.E_MSG_ID.MsgID_Arena_RewardRecord_VALUE, response.build().toByteArray());

		arenaData.setLogin(false);
	}

	/**
	 * 查看竞技场前100名
	 *
	 * @param playerController
	 */
	private void previewRank(PlayerController playerController) {
		WorldArenaData worldArenaData = GameServer.getInstance().getWorldArenaData();
		List<WorldArenaBean> rankList = worldArenaData.getUnderTargetRankList(100);
		S2C_ArenaPreviewRank.Builder response = S2C_ArenaPreviewRank.newBuilder();
		List<String> ids = new ArrayList<>();
		for (WorldArenaBean rank : rankList) {
			ids.add(rank.getObjectIndex());
		}

		List<PlayerModel> playerListByIndex = playerService.getPlayerListByIndex(ids);
		int size = rankList.size();
		for (int i = 0; i < size; i++) {
			SGCommonProto.ArenaPlayerInfo.Builder builder = SGCommonProto.ArenaPlayerInfo.newBuilder();
			builder.setRank(i + 1);
			PlayerModel player = getPlayerInList(playerListByIndex, rankList.get(i).getObjectIndex());
			if (player != null) {
				builder.setName(player.getName());
				builder.setCamp(SGCommonProto.E_CAMP_TYPE.forNumber(player.getCamp()));
				builder.setObjectIndex(player.getObjectIndex());
				builder.setFightingCapacity(player.getFc());
				builder.setMasterId(player.getMaster());
				builder.setAvatar(player.getAvatar());
			}
			response.addPlayers(builder);
		}

		LogUtils.debug("返回给客户端竞技场前100名 ： " + response.toString());
		// 返回给客户端
		playerController.sendMsg(SGMainProto.E_MSG_ID.MsgID_Arena_PreviewRank_VALUE, response.build().toByteArray());
	}

	/**
	 * 获取玩家的竞技场排名
	 *
	 * @param playerController
	 * @param data
	 */
	private void getPlayerArenaRankInfo(PlayerController playerController, byte[] data) throws ParseException {
		ArenaData arenaData = playerController.getPlayer().getArenaData();
		// TODO 测试专用
		// if(CodeFactory.TEST){
		// arenaData.reset();
		// }

		S2C_ArenaGetArenaInfo.Builder response = S2C_ArenaGetArenaInfo.newBuilder();
		// 自己的排名
		WorldArenaData worldArenaData = GameServer.getInstance().getWorldArenaData();
		int myRank = worldArenaData.getArenaRankByObjectIndex(playerController.getObjectIndex());
		arenaData.changeMaxRank(myRank);
		List<WorldArenaBean> rankList = getArenaRanksWithMe(playerController, myRank);
		List<String> playerIds = new ArrayList<>();
		for (WorldArenaBean rank : rankList) {
			playerIds.add(rank.getObjectIndex());
		}
		List<PlayerModel> playerListByIndex = playerService.getPlayerListByIndex(playerIds);

		for (WorldArenaBean rank : rankList) {
			SGCommonProto.ArenaPlayerInfo.Builder builder = SGCommonProto.ArenaPlayerInfo.newBuilder();
			if (StringUtils.isNullOrEmpty(rank.getObjectIndex())) { // 自己是最后一位需要补充一个扫荡对象
				builder.setRank(myRank + 100);
				builder.setName(LoadUtils.getRandomPlayerName());
				builder.setCamp(SGCommonProto.E_CAMP_TYPE.forNumber(playerController.getPlayer().camp));
				builder.setFightingCapacity(
						playerController.getPlayer().fc > 10 ? playerController.getPlayer().fc - 10 : 10);
				builder.setMasterId(playerController.getPlayer().master);
			} else {
				builder.setRank(worldArenaData.getArenaRankByObjectIndex(rank.getObjectIndex()));
				PlayerModel player = getPlayerInList(playerListByIndex, rank.getObjectIndex());
				if (player != null) {
					builder.setName(player.getName());
					builder.setCamp(SGCommonProto.E_CAMP_TYPE.forNumber(player.getCamp()));
					builder.setObjectIndex(player.getObjectIndex());
					builder.setFightingCapacity(player.getFc());
					builder.setMasterId(player.getMaster());
					builder.setAvatar(player.getAvatar());
				} else {
					LogUtils.debug("根据玩家的索引无法查到玩家， 索引为: " + rank.getObjectIndex());
					// playerController.sendWarn(WordFactory.SERVER_DATA_ERROR);
					worldArenaData.deleteArenaRankByObjectIndex(rank.getObjectIndex());
					continue;
				}
			}
			response.addPlayers(builder);
		}

		ChallengeInfo challengeInfo = playerController.getPlayer().getExtInfo(ChallengeInfo.class);
		//int yesRank = worldArenaData.getYesterdayArenaRankByObjectIndex(playerController.getObjectIndex());
		response.setHasRewardGoods(challengeInfo.getArenaData().checkHasExchangeReward(myRank));
		response.setMaxRank(arenaData.getMaxRank());
		response.setCurrentServerTime(DataFactory.currentTime);
		// 首次领奖需要在开服后的第二天才能领取
		response.setHasRewardToday(
				CoreUtils.isTodayByOffset(WorldInfoFactory.getInstance().getStartServerTime().getTime(),
						DataFactory.currentTime, ConstantFactory.DEFAULT_RESET_RECEIVE_REWARD_HOUR) ? true
								: CoreUtils.isTodayByOffset(arenaData.getLastRewardTime(), DataFactory.currentTime,
										ConstantFactory.DEFAULT_RESET_RECEIVE_REWARD_HOUR));
		response.setTodayChallengeTimes(arenaData.getTodayChallengeTimes());
		response.setTodayRemainTimes(arenaData.getRemainTodayChallengeTimes());
		response.setYesterdayRank(worldArenaData.getYesterdayArenaRankByObjectIndex(playerController.getObjectIndex()));

		List<ArenaRewardRecordDB> records = arenaData.getRewardRecords();
		for (ArenaRewardRecordDB record : records) {
			SGCommonProto.RewardInfo.Builder info = SGCommonProto.RewardInfo.newBuilder();
			info.setId(record.getId());
			info.setNum(record.getNum());
			info.setType(SGCommonProto.E_GOODS_TYPE.forNumber(record.getType()));
			response.addRewardInfo(info);
		}

		List<Integer> ids = arenaData.getAlreadyRewardIds();
		for (Integer id : ids) {
			response.addAlreadyRewardIds(id);
		}

		LogUtils.debug("返回给客户端玩家的竞技场排名 ： " + response.toString());
		// 返回给客户端
		playerController.sendMsg(SGMainProto.E_MSG_ID.MsgID_Arena_GetArenaInfo_VALUE, response.build().toByteArray());

	}

	/**
	 * 获取用户
	 *
	 * @param playerListByIndex
	 * @param objectIndex
	 * @return
	 */
	private PlayerModel getPlayerInList(List<PlayerModel> playerListByIndex, String objectIndex) {
		int index = playerListByIndex.indexOf(new PlayerModel(objectIndex));
		if(index >= 0)
			return playerListByIndex.get(index);

		return null;
	}

	/**
	 * 客户端发起挑战成功某位玩家
	 *
	 * @param playerController
	 * @param data
	 */
	private void arenaChallenge(PlayerController playerController, byte[] data) {
		C2S_ArenaChallenge request = null;
		try {
			request = C2S_ArenaChallenge.parseFrom(data);
		} catch (InvalidProtocolBufferException e) {
			e.printStackTrace();
		}
		if (request == null) {
			playerController.sendWarn(WordFactory.PARAM_ERROR);
			return;
		}
		ArenaData arenaData = playerController.getPlayer().getArenaData();
		LogUtils.debug("当前挑战的挑战次数剩余 :" + arenaData.getRemainTodayChallengeTimes());
		if (!arenaData.isChallengeTimesEnough()) {
			// TODO 挑战次数已经用完
			LogUtils.debug("挑战次数已经用完,当前挑战次数剩余 :" + arenaData.getRemainTodayChallengeTimes());
			playerController.sendWarn(WordFactory.ARENA_TIMES_NOT_ENOUGH);
			return;
		}

		int targetRank = request.getTargetRank();
		WorldArenaData worldArenaData = GameServer.getInstance().getWorldArenaData();
		int myRank = worldArenaData.getArenaRankByObjectIndex(playerController.getObjectIndex());
		LogUtils.debug("arenaChallenge， myRank: " + myRank + ", targetRank: " + targetRank);
		if(targetRank < playerController.getArenaChallengeMaxRank())
		{
			//非法请求，不能挑战超过的名次
			LogUtils.error("竞技场挑战参数非法,最高能挑战第" + playerController.getArenaChallengeMaxRank() + "名,参数名次为:" + targetRank);
			playerController.sendWarn(WordFactory.ILLEGAL_ERROR);
			return;
		}

		if (targetRank < myRank)
		{
			WorldArenaBean targetPlayerRank = worldArenaData.getArenaRankList().get(targetRank - 1);
			PlayerModel playerModel = playerService.getPlayerByIndex(targetPlayerRank.getObjectIndex());
			Player target = new Player(playerModel);
			targetPlayerRank.setBattle(true);
//			// TODO 自己测试
			if (CoreUtils.isFunctionTestAccount(playerController.getPlayer().getAccount())) {
				arenaBattleEnd(playerController, playerModel.getObjectIndex(), true);
				return;
			}
			// startBattle之前检测战斗中的卡牌数量
			String rs = MsgUtils.checkBattleCardCount(playerController.getPlayer());
			if (!com.douqu.game.core.util.StringUtils.isNullOrEmpty(rs)) {
				playerController.sendWarn(rs);
				return;
			}
			StableDataConfig stableDataConfig = DataFactory.getInstance().getGameObject(DataFactory.STABLE_DATA_KEY,
					E_StableDataType.ARENA_MAP.getCode());
			MsgUtils.startBattle(playerController, SGCommonProto.E_BATTLE_TYPE.BATTLE_TYPE_ARENA,
					E_BattleDetailType.PVP_AI_ARENA, target.getObjectIndex(),
					new BattleInitParam(stableDataConfig.intValue),
					new RequestParam(RequestParam.PARAM_PLAYER_TARGET, target));
		} else {
			// TODO 目标位置比自己低
			LogUtils.debug("目标位置比自己高");
			playerController.sendWarn(WordFactory.ARENA_TARGET_LOWER_THAN_ME);
			return;
		}
	}

	/**
	 * 战斗服务器结束竞技场挑战回调
	 *
	 * @param playerController
	 * @param targetIndex
	 */
	public void arenaBattleEnd(PlayerController playerController, String targetIndex, boolean win) {
		ArenaData arenaData = playerController.getPlayer().getArenaData();
		WorldArenaData worldArenaData = GameServer.getInstance().getWorldArenaData();
		int targetRank = worldArenaData.getArenaRankByObjectIndex(targetIndex);
		int myRank = worldArenaData.getArenaRankByObjectIndex(playerController.getObjectIndex());
		WorldArenaBean targetPlayerRank = worldArenaData.getArenaRankList().get(targetRank - 1);
		targetPlayerRank.setBattle(false);
		LogUtils.debug("竞技场挑战结果数------>>>> ： " + (win ? "胜利" : "失败"));
		//检测开服活动是否完成
		playerController.getPlayer().getSevenDayData().checkAllRewardState(SevenDayFactory.EVENT_TYPE_14,1);

		// 任务检测
		if (win) {
			if (worldArenaData.swapArenaRank(myRank, targetRank)) {
				myRank = targetRank;
				arenaData.winBattle();
				// 检测任务是否完成
				playerController.getPlayer().getExtInfo(TaskInfo.class).check(TaskFactory.TASK_TARAGET_ARENA, 1);

				//检测开服活动是否完成
				playerController.getPlayer().getSevenDayData().checkAllRewardState(SevenDayFactory.EVENT_TYPE_17,myRank);

			} else {
				// TODO 交换位置失败
				LogUtils.error("交换位置失败");
				playerController.sendWarn(WordFactory.SERVER_DATA_ERROR);
				return;
			}
			// 发放扫荡奖励
			StableDataConfig stableDataConfig = DataFactory.getInstance().getGameObject(DataFactory.STABLE_DATA_KEY,
					E_StableDataType.ARENA_PASS_REWARD.getCode());
			BagInfo bagInfo = playerController.getPlayer().getExtInfo(BagInfo.class);
			bagInfo.addGoods(stableDataConfig.goods, null);

			String content;
			if (!StringUtils.isNullOrEmpty(content = NoticeUtils.getScrollNotice(E_ScrollNoticeType.ARENA_RANK_UP,
					playerController.getName(), myRank))) {
				// GameServer.getInstance().getWorldManager().dispatchGet(content);
				playerController.getPlayer().getChangeGoods().getNotices().add(content);
			}
		}

		// 检测任务是否完成
		playerController.getPlayer().getExtInfo(TaskInfo.class).check(TaskFactory.TASK_TARAGET_MAIN_ARENA_BATTLE, 1);

		//检测开服活动是否完成
		playerController.getPlayer().getSevenDayData().checkAllRewardState(SevenDayFactory.EVENT_TYPE_14,1);


		S2C_ArenaChallenge.Builder response = S2C_ArenaChallenge.newBuilder();
		response.setWin(win);
		List<WorldArenaBean> rankList = getArenaRanksWithMe(playerController, myRank);
		List<String> ids = new ArrayList<>();
		for (WorldArenaBean rank : rankList) {
			ids.add(rank.getObjectIndex());
		}
		List<PlayerModel> playerListByIndex = playerService.getPlayerListByIndex(ids);
		for (WorldArenaBean rank : rankList) {
			SGCommonProto.ArenaPlayerInfo.Builder builder = SGCommonProto.ArenaPlayerInfo.newBuilder();
			if (StringUtils.isNullOrEmpty(rank.getObjectIndex())) {
				builder.setRank(myRank + 1);
				builder.setName(LoadUtils.getRandomPlayerName());
				builder.setCamp(SGCommonProto.E_CAMP_TYPE.forNumber(playerController.getPlayer().camp));
				builder.setFightingCapacity(
						playerController.getPlayer().fc > 10 ? playerController.getPlayer().fc - 10 : 10);
				builder.setMasterId(playerController.getPlayer().master);
			} else {
				builder.setRank(worldArenaData.getArenaRankByObjectIndex(rank.getObjectIndex()));
				PlayerModel player = getPlayerInList(playerListByIndex, rank.getObjectIndex());
				if (player != null) {
					builder.setName(player.getName());
					builder.setCamp(SGCommonProto.E_CAMP_TYPE.forNumber(player.getCamp()));
					builder.setObjectIndex(player.getObjectIndex());
					builder.setFightingCapacity(player.getFc());
					builder.setMasterId(player.getMaster());
					builder.setAvatar(player.getAvatar());
				} else {
					LogUtils.warn("根据玩家的索引无法查到玩家， 索引为: " + rank.getObjectIndex());
					// playerController.sendWarn(WordFactory.SERVER_DATA_ERROR);
					worldArenaData.deleteArenaRankByObjectIndex(rank.getObjectIndex());
					continue;
				}
			}
			response.addPlayers(builder);

		}
		arenaData.changeMaxRank(myRank);
		arenaData.addChallengeTimes(DataFactory.currentTime);
		LogUtils.debug("已经挑战次数剩余 ： " + arenaData.getRemainTodayChallengeTimes());
		LogUtils.debug("返回给客户端挑战成功某位玩家 ： " + response.toString());
		// 返回给客户端
		playerController.sendMsg(SGMainProto.E_MSG_ID.MsgID_Arena_Challenge_VALUE, response.build().toByteArray());
	}

	/**
	 * 领取当日奖励
	 *
	 * @param playerController
	 */
	private void getDailyReward(PlayerController playerController) {
		ArenaData arenaData = playerController.getPlayer().getArenaData();
		long lastRewardTime = arenaData.getLastRewardTime();
		if (lastRewardTime == 0) {
			// 首次领奖需要在开服后的第二天才能领取
			if (CoreUtils.isTodayByOffset(WorldInfoFactory.getInstance().getStartServerTime().getTime(),
					DataFactory.currentTime, ConstantFactory.DEFAULT_RESET_RECEIVE_REWARD_HOUR)) {
				playerController.sendWarn(WordFactory.ONLY_SECOND_DAYS_AFTER_TAKING_OFF);
				return;
			}
			// WorldInfo worldInfo =
			// GameServer.getInstance().getWorldManager().getWorldInfo();
			// Date startServerTime = worldInfo.getStartServerTime();
			// try {
			//
			// int day = Utils.daysBetween(startServerTime, new Date());
			// if(day <= 1){
			//
			// }
			// } catch (ParseException e) {
			// e.printStackTrace();
			// LogUtils.error(e);
			// }
		}

		if (CoreUtils.isTodayByOffset(lastRewardTime, DataFactory.currentTime, ConstantFactory.DEFAULT_RESET_RECEIVE_REWARD_HOUR)) {
			LogUtils.error("今天已经领取过奖励");
			// TODO 今天已经领取过奖励
			playerController.sendWarn(WordFactory.ARENA_DAILY_HAS_REWARD);
			return;
		}

		// TODO 领取奖励
		List<ArenaDailyConfig> rewardConfigs = DataFactory.getInstance()
				.getDataList(DataFactory.ARENA_DAILY_REWARD_KEY);
		int myRank = GameServer.getInstance().getWorldArenaData()
				.getYesterdayArenaRankByObjectIndex(playerController.getObjectIndex());
		myRank = myRank <= 0 ? Integer.MAX_VALUE : myRank;
		ArenaDailyConfig reward = null;
		for (ArenaDailyConfig r : rewardConfigs) {
			if (myRank >= r.minRank && myRank <= r.maxRank) {// 在最大和最小排名之间
				reward = r;
				break;
			}
		}
		if (reward == null) {
			reward = rewardConfigs.get(rewardConfigs.size() - 1);
		}

		BagInfo bagInfo = playerController.getPlayer().getExtInfo(BagInfo.class);
		bagInfo.addGoods(reward.dailyReward, null);

		S2C_ArenaGetDailyReward.Builder response = S2C_ArenaGetDailyReward.newBuilder();
		response.setCurrentServerTime(DataFactory.currentTime);
		arenaData.setLastRewardTime(DataFactory.currentTime);
		LogUtils.debug("返回给客户端竞技场每日领取奖励结果 ： " + response.toString());
		// 返回给客户端
		playerController.sendMsg(SGMainProto.E_MSG_ID.MsgID_Arena_GetDailyReward_VALUE, response.build().toByteArray());
	}

	/**
	 * 根据自己的排名获取竞技场排名情况
	 *
	 * @param myRank
	 * @return
	 */
	private List<WorldArenaBean> getArenaRanksWithMe(PlayerController playerController, int myRank) {
		List<WorldArenaBean> rankList = new ArrayList<WorldArenaBean>();
		int paramY = 0;
		WorldArenaData worldArenaData = GameServer.getInstance().getWorldArenaData();
		if (myRank < 7) {// 1-6名都加载前六名
			rankList.addAll(worldArenaData.getUnderTargetRankList(6));
		}
		else if (myRank < 15) {// 加载1-myRank的所有数据
			rankList.addAll(worldArenaData.getUnderTargetRankList(myRank));
			paramY = 1;
		}
		else
		{
			if(paramY == 0) {
				if (myRank < 31) {
					paramY = 1;
				} else if (myRank < 101) {
					paramY = 3;
				} else if (myRank < 501) {
					paramY = 10;
				} else if (myRank < 1001) {
					paramY = 15;
				} else if (myRank < 3001) {
					paramY = 60;
				} else if (myRank < 6001) {
					paramY = 100;
				} else if (myRank < 100001) {
					paramY = 150;
				}
			}
		}

		if (rankList.size() == 0) {
			// 取出前10名
			rankList.addAll(worldArenaData.getUnderTargetRankList(10));
			WorldArenaBean worldArenaBean = getEnableChallengeTarget(myRank, paramY, 4);
			playerController.setArenaChallengeMaxRank(worldArenaBean.getRank());//玩家能挑战的最高名次
			rankList.add(worldArenaBean);
			rankList.add(getEnableChallengeTarget(myRank, paramY, 3));
			rankList.add(getEnableChallengeTarget(myRank, paramY, 2));
			// 添加自己
			rankList.add(GameServer.getInstance().getWorldArenaData().getArenaRankInfo(myRank));
		}
		else
		{
			playerController.setArenaChallengeMaxRank(rankList.get(0).getRank());
		}

		if (rankList.get(rankList.size() - 1).getRank() == myRank) { // 自己是最后一个，增加一个扫荡对象
			WorldArenaBean temp = getEnableSweepTarget(myRank, paramY);
			if (temp != null && !rankList.contains(temp)) {
				rankList.add(temp);
			}
		}

		return rankList;
	}

	/**
	 * 获取适合的扫荡对象
	 *
	 * @param myRank
	 * @param paramY
	 * @return
	 */
	private WorldArenaBean getEnableSweepTarget(int myRank, int paramY) {
		int size = GameServer.getInstance().getWorldArenaData().getArenaRankList().size();
		if (myRank == size) { // 我就是最后一位
			return new WorldArenaBean();
		}
		if (myRank + paramY > size) { // 随机值会大于总数据长度
			paramY = size - myRank;
		}
		int targetRank = myRank + 1 + (paramY > 0 ? Utils.getRandom(paramY) : 0);
		return GameServer.getInstance().getWorldArenaData().getArenaRankInfo(targetRank);
	}

	/**
	 * 获取合适的空闲挑战对象
	 *
	 * @param myRank
	 * @param paramY
	 * @param rate
	 * @return
	 */
	private WorldArenaBean getEnableChallengeTarget(int myRank, int paramY, int rate) {
		int targetRank = myRank - 1 - paramY * (rate - 1) - Utils.getRandom(paramY);
		return GameServer.getInstance().getWorldArenaData().getArenaRankInfo(targetRank);
	}

	/**
	 * 添加资源领取记录
	 *
	 * @param arenaData
	 */
	private void addRewardRecord(ArenaData arenaData, GoodsData goodsData) {
		ArenaRewardRecordDB record = new ArenaRewardRecordDB(goodsData.type, goodsData.id);
		int index = arenaData.getRewardRecords().indexOf(record);
		if (index > -1) {
			arenaData.getRewardRecords().get(index).addNum(goodsData.value);
		} else {
			record.setNum(goodsData.value);
			arenaData.getRewardRecords().add(record);
		}
	}

	/*************************************
	 * 竞技场end
	 ***********************************************************************************/

	/*************************************
	 * 官阶战star
	 ***********************************************************************************/

	/**
	 * 初始化页面信息
	 *
	 * @param playerController
	 * @param data
	 * @param code
	 */
	private void initInfo(PlayerController playerController, byte[] data, int code) throws ParseException {
		OfficialRankData rankData = playerController.getPlayer().getOfficialData();
		// if(CodeFactory.TEST){
		// rankData.reset();
		// }
		WorldOfficialBean rankBean = getOfficialRankInfo().getRankInfoByObjectIndex(playerController.getPlayer());
		int myRank = rankBean == null ? 15 : rankBean.getRankId();
		SGChallengeProto.S2C_InitInfo.Builder response = SGChallengeProto.S2C_InitInfo.newBuilder();
		response.setCurrentServerTime(DataFactory.currentTime);
		// 首次领奖需要在开服后的第二天才能领取
		response.setHasRewardToday(
				CoreUtils.isTodayByOffset(WorldInfoFactory.getInstance().getStartServerTime().getTime(),
						DataFactory.currentTime, ConstantFactory.DEFAULT_RESET_RECEIVE_REWARD_HOUR) ? true
								: CoreUtils.isTodayByOffset(rankData.getLastRewardTime(), DataFactory.currentTime,
										ConstantFactory.DEFAULT_RESET_RECEIVE_REWARD_HOUR));
		response.setTodayChallengeTimes(rankData.getTodayChallengeTimes());
		response.setTodayRemainTimes(rankData.getTodayRemainChallengeTimes());
		response.setOfficialRankId(myRank);
		response.setHasIntegralRewardGoods(rankData.checkHasIntegralExchangeReward());

		WorldOfficialBean yseRankBean = getOfficialRankInfo()
				.getYesterdayRankInfoByObjectIndex(playerController.getPlayer());
		int yesRank = yseRankBean == null ? 15 : yseRankBean.getRankId();
		response.setYesterdayRank(yesRank);
		response.setHasRewardGoods(rankData.checkHasExchangeReward(myRank));
		response.setMaxRank(rankData.getMaxOfficialRankId());

		List<WorldOfficialBean> top5Player = getOfficialRankInfo().getTop5Player(playerController.getPlayer());
		if (top5Player == null) {
			LogUtils.debug("获取前五名玩家返回空，可能是阵营错误！！");
			playerController.sendWarn(WordFactory.SERVER_DATA_ERROR);
			return;
		}

		List<String> playerIds = new ArrayList<>();
		for (WorldOfficialBean rank : top5Player) {
			playerIds.add(rank.getObjectIndex());
		}

		List<PlayerModel> playerListByIndex = playerService.getPlayerListByIndex(playerIds);

		SGCommonProto.OfficialRankObject.Builder obj;
		for (WorldOfficialBean bean : top5Player) {
			obj = SGCommonProto.OfficialRankObject.newBuilder();
			obj.setOfficialRankId(bean.getRankId());
			obj.setName(bean.getName() + "");
			if (!StringUtils.isNullOrEmpty(bean.getObjectIndex())) {
				obj.setObjectIndex(bean.getObjectIndex());
				PlayerModel player = getPlayerInList(playerListByIndex, bean.getObjectIndex());
				if (player != null) {
					obj.setName(player.getName());
					obj.setAvatar(player.getAvatar());
					obj.setCamp(player.getCamp());
					obj.setMasterId(player.getMaster());
					obj.setFightingCapacity(player.getFc());
				} else {
					LogUtils.debug("根据玩家的索引无法查到玩家， 索引为: " + bean.getObjectIndex());
					// playerController.sendWarn(WordFactory.SERVER_DATA_ERROR);
					getOfficialRankInfo().deleteRankInfo(player.getCamp(), bean.getRankId(), bean.getObjectIndex());
					continue;
				}
			}
			response.addPlayers(obj);
		}

		List<ArenaRewardRecordDB> records = rankData.getRewardRecords();
		for (ArenaRewardRecordDB record : records) {
			SGCommonProto.RewardInfo.Builder info = SGCommonProto.RewardInfo.newBuilder();
			info.setId(record.getId());
			info.setNum(record.getNum());
			info.setType(SGCommonProto.E_GOODS_TYPE.forNumber(record.getType()));
			response.addRewardInfo(info);
		}

		List<Integer> ids = rankData.getAlreadyRewardIds();
		for (Integer id : ids) {
			response.addAlreadyRewardIds(id);
		}

		response.addAllAlreadyRewardIds(rankData.getIntegralRewardIds());

		LogUtils.debug("返回给客户端数据：" + response.toString());
		// 返回给客户端
		playerController.sendMsg(code, response.build().toByteArray());
	}

	/**
	 * 查看官阶对应的人员
	 *
	 * @param playerController
	 * @param data
	 * @param code
	 */
	private void previewRank(PlayerController playerController, byte[] data, int code) {
		SGChallengeProto.C2S_PreviewRank request = null;
		try {
			request = SGChallengeProto.C2S_PreviewRank.parseFrom(data);
		} catch (InvalidProtocolBufferException e) {
			e.printStackTrace();
		}
		if (request == null) {
			playerController.sendWarn(WordFactory.PARAM_ERROR);
			return;
		}
		int targetRankId = request.getOfficialRankId();
		LogUtils.debug("previewRank targetRankId：" + targetRankId);
		SGChallengeProto.S2C_PreviewRank.Builder response = SGChallengeProto.S2C_PreviewRank.newBuilder();
		List<WorldOfficialBean> players = getOfficialRankInfo().getTargetRankPlayer(playerController.getPlayer(),
				targetRankId);
		if (players == null) {
			playerController.sendWarn(WordFactory.PARAM_ERROR);
			return;
		}

		List<String> ids = new ArrayList<>();
		for (WorldOfficialBean rank : players) {
			ids.add(rank.getObjectIndex());
		}
		List<PlayerModel> playerListByIndex = playerService.getPlayerListByIndex(ids);

		SGCommonProto.OfficialRankObject.Builder obj;
		for (WorldOfficialBean bean : players) {
			obj = SGCommonProto.OfficialRankObject.newBuilder();
			obj.setOfficialRankId(bean.getRankId());
			obj.setPosition(bean.getPosition());
			if (!StringUtils.isNullOrEmpty(bean.getObjectIndex())) {
				obj.setObjectIndex(bean.getObjectIndex());
				PlayerModel player = getPlayerInList(playerListByIndex, bean.getObjectIndex());
				if (player != null) {
					obj.setName(player.getName());
					obj.setAvatar(player.getAvatar());
					obj.setCamp(player.getCamp());
					obj.setMasterId(player.getMaster());
					obj.setFightingCapacity(player.getFc());
				} else {
					LogUtils.error("根据玩家的索引无法查到玩家， 索引为: " + bean.getObjectIndex());
					getOfficialRankInfo().deleteRankInfo(player.getCamp(), targetRankId, bean.getObjectIndex());
					// playerController.sendWarn(WordFactory.SERVER_DATA_ERROR);
					continue;
				}
			} else if (!StringUtils.isNullOrEmpty(bean.getName())) {
				obj.setName(bean.getName());
			} else {
				obj.setName(LoadUtils.getRandomPlayerName());
			}
			response.addPlayers(obj);
		}

		LogUtils.debug("返回给客户端数据：" + response.toString());
		// 返回给客户端
		playerController.sendMsg(code, response.build().toByteArray());
	}

	/**
	 * 挑战对应官阶
	 *
	 * @param playerController
	 * @param data
	 * @param code
	 */
	private void challengeRank(PlayerController playerController, byte[] data, int code) {
		SGChallengeProto.C2S_ChallengeRank request = null;
		try {
			request = SGChallengeProto.C2S_ChallengeRank.parseFrom(data);
		} catch (InvalidProtocolBufferException e) {
			e.printStackTrace();
		}
		if (request == null) {
			playerController.sendWarn(WordFactory.PARAM_ERROR);
			return;
		}

		int targetRankId = request.getOfficialRankId();
		OfficialRankConfig officialRankConfig = DataFactory.getInstance().getGameObject(DataFactory.OFFICIAL_RANK_KEY,
				playerController.getPlayer().camp * 100 + targetRankId);

		if (officialRankConfig == null) {
			LogUtils.error("参数错误");
			playerController.sendWarn(WordFactory.PARAM_ERROR);
			return;
		}
		int position = request.getPosition();
		if (position < 0) {
			LogUtils.debug("参数错误");
			playerController.sendWarn(WordFactory.PARAM_ERROR);
			return;
		}

		OfficialRankData officialRankData = playerController.getPlayer().getOfficialData();
		if (!officialRankData.isChallengeTimesEnough()) {
			// TODO 挑战次数已经用完
			LogUtils.debug("挑战次数已经用完,当前挑战次数剩余 :" + officialRankData.getTodayRemainChallengeTimes());
			playerController.sendWarn(WordFactory.ARENA_TIMES_NOT_ENOUGH);
			return;
		}

		LogUtils.debug("挑战的官阶id：" + targetRankId + ", 位置： " + position);
		WorldOfficialBean targetPositionPlayer = getOfficialRankInfo()
				.getTargetPositionPlayer(playerController.getPlayer().camp, targetRankId, position);
		if (targetPositionPlayer == null) {
			LogUtils.debug("挑战的目标找不到");
			playerController.sendWarn(WordFactory.PARAM_ERROR);
			return;
		}
		// 自己所在的官阶排行
		WorldOfficialBean myRankBean = getOfficialRankInfo().getRankInfoByObjectIndex(playerController.getPlayer());
		int myRankId = myRankBean == null ? 0 : myRankBean.getRankId();
		if (myRankId == 0) { // 第一次挑战
			if (targetRankId != 14) {// 首次挑战异常
				LogUtils.debug("不能越阶挑战 myRank: " + myRankId);
				playerController.sendWarn(WordFactory.OFFICIAL_NOT_JUMP_RANK_CHALLENGE);
				return;
			}
//			// TODO 自己测试
			if (CoreUtils.isFunctionTestAccount(playerController.getPlayer().getAccount())) {
				challengeResult(playerController, playerController.getPlayer().camp * 100 + targetRankId, position,
						true);
				playerController.sendWarn(WordFactory.PARAM_ERROR);
				return;
			}
		} else {
			if (targetRankId != myRankId - 1) {
				LogUtils.debug("不能越阶挑战 myRank: " + myRankId);
				playerController.sendWarn(WordFactory.OFFICIAL_NOT_JUMP_RANK_CHALLENGE);
				return;
			}

//			// TODO 自己测试
			if (CoreUtils.isFunctionTestAccount(playerController.getPlayer().getAccount())) {
				challengeResult(playerController, playerController.getPlayer().camp * 100 + targetRankId, position,
						true);
				playerController.sendWarn(WordFactory.PARAM_ERROR);
				return;
			}
		}

		String param = playerController.getPlayer().camp * 100 + targetRankId + ConstantFactory.UNDERLINE + position
				+ ConstantFactory.UNDERLINE;
		if (targetPositionPlayer.isPlayer()) {
			// startBattle之前检测战斗中的卡牌数量
			String rs = MsgUtils.checkBattleCardCount(playerController.getPlayer());
			if (!com.douqu.game.core.util.StringUtils.isNullOrEmpty(rs)) {
				playerController.sendWarn(rs);
				return;
			}
			MsgUtils.startBattle(playerController, SGCommonProto.E_BATTLE_TYPE.BATTLE_TYPE_OFFICIAL_RANK,
					E_BattleDetailType.PVP_AI_OFFICIAL_RANK, param + targetPositionPlayer.getObjectIndex(),
					new BattleInitParam(officialRankConfig.mapId));
		} else {
			// startBattle之前检测战斗中的卡牌数量
			String rs = MsgUtils.checkBattleCardCount(playerController.getPlayer());
			if (!com.douqu.game.core.util.StringUtils.isNullOrEmpty(rs)) {
				playerController.sendWarn(rs);
				return;
			}
			MsgUtils.startBattle(playerController, SGCommonProto.E_BATTLE_TYPE.BATTLE_TYPE_OFFICIAL_RANK,
					E_BattleDetailType.PVE_OFFICIAL_RANK, param + request.getMasterName(),
					new BattleInitParam(officialRankConfig.mapId));
		}
	}

	/**
	 * 挑战结果
	 *
	 * @param playerController
	 * @param targetRankId
	 * @param targetPosition
	 * @param win
	 */
	public void challengeResult(PlayerController playerController, int targetRankId, int targetPosition, boolean win) {
		targetRankId = targetRankId % 100;
		WorldOfficialData worldOfficialData = getOfficialRankInfo();
		LogUtils.debug("结算之前的数据:" + worldOfficialData);
		// 自己所在的官阶排行

		// int myRankId = myRankBean == null? 0 : myRankBean.getRankId();
		// int myPosition = myRankBean == null ? -1 : myRankBean.getPosition();
		final int camp = playerController.getPlayer().camp;
		OfficialRankData myOfficialRank = playerController.getPlayer().getOfficialData();
		// 增加挑战次数
		myOfficialRank.addChallengeTimes(DataFactory.currentTime);
		LogUtils.debug("当前挑战次数剩余 : " + myOfficialRank.getTodayRemainChallengeTimes());
		LogUtils.debug("官阶挑战结果 ------->>>>: " + (win ? "胜利" : "失败"));
		if (win) {
			WorldOfficialBean targetPlayer = worldOfficialData.getTargetPositionPlayer(camp, targetRankId,
					targetPosition);
			if (targetPlayer == null) {
				LogUtils.debug("挑战的目标找不到");
				playerController.sendWarn(WordFactory.PARAM_ERROR);
				return;
			}

			WorldOfficialBean myRankBean = worldOfficialData.getRankInfoByObjectIndex(playerController.getPlayer());
			LogUtils.debug("自己的官阶数据:" + myRankBean);

			if (targetPlayer.isPlayer()) {
				TwoTuple<Player, PlayerController> playerResult = GameServer.getInstance().getWorldManager()
						.getPlayerResult(targetPlayer.getObjectIndex());
				if (playerResult.getFirst() != null) {
					OfficialRankData targetOfficialRank = playerResult.getFirst().getOfficialData();
					targetOfficialRank.setCurRankId(myRankBean == null ? 15 : myRankBean.getRankId());// 设置对方的新官阶

					if (playerResult.getSecond() == null) {
						// 离线,要保存玩家数据
						GameServer.getInstance().savePlayer(playerResult.getFirst());
					}
				}
			}

			myOfficialRank.setCurRankId(targetRankId);// 设置我的新官阶

			final String beforeIndex = targetPlayer.getObjectIndex();
			final String beforeName = targetPlayer.getName();

			// 将目标设置成自己
			targetPlayer.setObjectIndex(playerController.getObjectIndex());
			targetPlayer.setName(playerController.getName());

			if (myRankBean == null) {// 第一次，直接赋值
				firstAttachThisRank(playerController, targetRankId);
			} else {
				// 交换位置
				myRankBean.setObjectIndex(beforeIndex);
				myRankBean.setName(beforeName);
				// WorldOfficialRankBean myTargetBean =
				// worldOfficialRankData.getTargetPositionPlayer(camp, myRankId, myPosition);
				// myTargetBean.setObjectIndex(targetPlayer.getObjectIndex());
				// myTargetBean.setName(targetPlayer.getName());

				if (targetRankId < myOfficialRank.getMaxOfficialRankId()) {
					firstAttachThisRank(playerController, targetRankId);
				}
			}

			String content;
			if (!StringUtils.isNullOrEmpty(content = NoticeUtils.getScrollNotice(E_ScrollNoticeType.OFFICIAL_RANK_UP,
					playerController.getName(), camp, camp * 100 + targetRankId))) {
				// GameServer.getInstance().getWorldManager().dispatchGet(content);
				playerController.getPlayer().getChangeGoods().getNotices().add(content);
			}
		}

		// 检测任务是否完成
		playerController.getPlayer().getExtInfo(TaskInfo.class).check(TaskFactory.TASK_TARAGET_MAIN_OFFICIALWAR, 1);

		//检测开服活动是否完成
		playerController.getPlayer().getSevenDayData().checkAllRewardState(SevenDayFactory.EVENT_TYPE_16,1);


		// 发放通过奖励
		BagInfo bagInfo = playerController.getPlayer().getExtInfo(BagInfo.class);
		OfficialRankConfig rankConfig = DataFactory.getInstance().getGameObject(DataFactory.OFFICIAL_RANK_KEY,
				playerController.getPlayer().camp * 100 + targetRankId);
		bagInfo.addGoods(rankConfig.passReward, null);
		LogUtils.debug("官阶战战斗结束：------>>>>" + (win ? " 胜利" : "失败"));

		LogUtils.debug("结算之后的数据:" + worldOfficialData);
	}

	/**
	 * 首次达到对应的官阶奖励
	 *
	 * @param playerController
	 * @param targetRankId
	 */
	private void firstAttachThisRank(PlayerController playerController, int targetRankId) {
		OfficialRankConfig configObj = DataFactory.getInstance().getGameObject(DataFactory.OFFICIAL_RANK_KEY,
				playerController.getPlayer().camp * 100 + targetRankId);
		BagInfo bagInfo = playerController.getPlayer().getExtInfo(BagInfo.class);
		bagInfo.addGoods(configObj.firstReward, null);
		playerController.getPlayer().getOfficialData().changeMaxOfficialRankId(targetRankId);
	}

	/**
	 * 扫荡对应官阶
	 *
	 * @param playerController
	 * @param data
	 * @param code
	 */
	private void sweepRank(PlayerController playerController, byte[] data, int code) {
		SGChallengeProto.C2S_SweepRank request = null;
		try {
			request = SGChallengeProto.C2S_SweepRank.parseFrom(data);
		} catch (InvalidProtocolBufferException e) {
			e.printStackTrace();
		}
		if (request == null) {
			playerController.sendWarn(WordFactory.PARAM_ERROR);
			return;
		}

		int targetRankId = request.getOfficialRankId();
		int position = request.getPosition();

		OfficialRankData officialRank = playerController.getPlayer().getOfficialData();
		if (!officialRank.isChallengeTimesEnough()) {
			// TODO 挑战次数已经用完
			LogUtils.debug("挑战次数已经用完,当前挑战次数剩余 :" + officialRank.getTodayRemainChallengeTimes());
			playerController.sendWarn(WordFactory.OFFICIAL_TIMES_NOT_ENOUGH);
			return;
		}

		LogUtils.debug("扫荡的官阶id：" + targetRankId + ", 位置： " + position);
		WorldOfficialBean targetPositionPlayer = getOfficialRankInfo()
				.getTargetPositionPlayer(playerController.getPlayer().camp, targetRankId, position);
		if (targetPositionPlayer == null) {
			LogUtils.debug("扫荡的目标找不到");
			playerController.sendWarn(WordFactory.PARAM_ERROR);
			return;
		}
		// 自己所在的官阶排行
		WorldOfficialBean myRankBean = getOfficialRankInfo().getRankInfoByObjectIndex(playerController.getPlayer());
		int myRankId = myRankBean == null ? 0 : myRankBean.getRankId();
		if (myRankId > targetRankId) {
			LogUtils.debug("不能扫荡比自己排名高度 myRank: " + myRankId);
			playerController.sendWarn(WordFactory.OFFICIAL_NOT_SWEEP_HEIGHT_PLAYER);
			return;
		}
		officialRank.addChallengeTimes(DataFactory.currentTime);
		LogUtils.debug("当前挑战次数剩余 : " + officialRank.getTodayRemainChallengeTimes());
		// 发放通过奖励
		BagInfo bagInfo = playerController.getPlayer().getExtInfo(BagInfo.class);
		OfficialRankConfig rankConfig = DataFactory.getInstance().getGameObject(DataFactory.OFFICIAL_RANK_KEY,
				playerController.getPlayer().camp * 100 + targetRankId);
		bagInfo.addGoods(rankConfig.passReward, null);

		SGChallengeProto.S2C_SweepRank.Builder response = SGChallengeProto.S2C_SweepRank.newBuilder();
		response.setOfficialRankId(myRankId);
		LogUtils.debug("返回给客户端数据：" + response.toString());
		// 返回给客户端
		playerController.sendMsg(code, response.build().toByteArray());

		// 检测副本通关任务
		playerController.getPlayer().getExtInfo(TaskInfo.class).check(TaskFactory.TASK_TARAGET_MAIN_OFFICIALWAR, 1);
	}

	/**
	 * 每日领取奖励
	 *
	 * @param playerController
	 * @param data
	 * @param code
	 */
	private void getDailyReward(PlayerController playerController, byte[] data, int code) {

		// 首次领奖需要在开服后的第二天才能领取
		if (CoreUtils.isTodayByOffset(WorldInfoFactory.getInstance().getStartServerTime().getTime(),
				DataFactory.currentTime, ConstantFactory.DEFAULT_RESET_RECEIVE_REWARD_HOUR)) {
			playerController.sendWarn(WordFactory.ONLY_SECOND_DAYS_AFTER_TAKING_OFF);
			return;
		}

		OfficialRankData officialRank = playerController.getPlayer().getOfficialData();
		long lastRewardTime = officialRank.getLastRewardTime();
		if (CoreUtils.isTodayByOffset(lastRewardTime, DataFactory.currentTime,
				ConstantFactory.DEFAULT_RESET_RECEIVE_REWARD_HOUR)) {
			LogUtils.debug("今天已经领取过奖励");
			// TODO 今天已经领取过奖励
			playerController.sendWarn(WordFactory.OFFICIAL_DAILY_HAS_REWARD);
			return;
		}

		// 自己所在的官阶排行
		WorldOfficialBean myRankBean = getOfficialRankInfo()
				.getYesterdayRankInfoByObjectIndex(playerController.getPlayer());
		int rankId = myRankBean == null ? 15 : myRankBean.getRankId();
		officialRank.setLastRewardTime(DataFactory.currentTime);
		// TODO 领取奖励
		OfficialRankConfig rankConfig = DataFactory.getInstance().getGameObject(DataFactory.OFFICIAL_RANK_KEY,
				playerController.getPlayer().camp * 100 + rankId);
		BagInfo bagInfo = playerController.getPlayer().getExtInfo(BagInfo.class);
		bagInfo.addGoods(rankConfig.dailyReward, null);
		S2C_ArenaGetDailyReward.Builder response = S2C_ArenaGetDailyReward.newBuilder();
		response.setCurrentServerTime(DataFactory.currentTime);
		LogUtils.debug("返回给客户端官阶战每日领取奖励结果 ： " + response.toString());
		// 返回给客户端
		playerController.sendMsg(code, response.build().toByteArray());
	}

	/**
	 * 兑换商店奖励
	 *
	 * @param playerController
	 * @param data
	 * @param code
	 */
	private void exchangeReward(PlayerController playerController, byte[] data, int code) {
		SGChallengeProto.C2S_ExchangeReward request = null;
		try {
			request = SGChallengeProto.C2S_ExchangeReward.parseFrom(data);
		} catch (InvalidProtocolBufferException e) {
			e.printStackTrace();
		}
		if (request == null) {
			playerController.sendWarn(WordFactory.PARAM_ERROR);
			return;
		}

		OfficialRankData officialRank = playerController.getPlayer().getOfficialData();
		int rewardId = request.getRewardId();
		if (officialRank.getAlreadyRewardIds().contains(rewardId)) {
			LogUtils.debug("官阶战该资源已经兑换过了");
			playerController.sendWarn(WordFactory.OFFICIAL_REWARD_GROUP_ALREADY_REWARD);
			return;
		}
		ExchangeRewardConfig rewardConfig = DataFactory.getInstance().getGameObject(DataFactory.REWARD_KEY, rewardId);
		if (rewardConfig == null || rewardConfig.type != E_ExchangeRewardType.OFFICIAL_RANK.getCode()) {
			LogUtils.debug("官阶战 rewardId 不存在：" + rewardId);
			playerController.sendWarn(WordFactory.PARAM_ERROR);
			return;
		}
		// 自己所在的官阶排行
		WorldOfficialBean myRankBean = getOfficialRankInfo().getRankInfoByObjectIndex(playerController.getPlayer());
		int myRankId = myRankBean == null ? 100 : myRankBean.getRankId();
		if (myRankId > rewardConfig.minRank) { // 自己的排名大于要求的最低排名，不符合领取条件
			// TODO error
			LogUtils.debug("官阶战自己的排名大于要求的最低排名，不符合领取条件 ");
			playerController.sendWarn(WordFactory.OFFICIAL_RANK_NOT_ENOUGH);
			return;
		}
		BagInfo bagInfo = playerController.getPlayer().getExtInfo(BagInfo.class);
		// 循环配置表检测自己的资源是否足够
		for (CommonData assets : rewardConfig.needAssets) {
			if (bagInfo.getAsset(assets.id) < assets.value) {// 自己拥有的小于配置的
				// TODO 资源不足
				LogUtils.error("官阶战兑换奖励资源不足 ");
				playerController.sendWarn(WordFactory.ASSET_NOT_ENOUGH, assets.id);
				return;
			}
		}
		officialRank.getAlreadyRewardIds().add(rewardId);
		GoodsData[] consumeData = new GoodsData[rewardConfig.needAssets.length];
		for (int i = 0; i < rewardConfig.needAssets.length; i++) {
			consumeData[i] = new GoodsData(SGCommonProto.E_GOODS_TYPE.GOODS_TYPE_ASSETS_VALUE,
					rewardConfig.needAssets[i].id, rewardConfig.needAssets[i].value);
		}
		bagInfo.addGoods(rewardConfig.reward, consumeData);
		// bagInfo.reduceAsset(rewardConfig.needAssets);

		for (GoodsData goodsData : rewardConfig.reward) {
			addRewardRecord(officialRank, goodsData);
		}
		SGChallengeProto.S2C_ExchangeReward.Builder response = SGChallengeProto.S2C_ExchangeReward.newBuilder();
		response.setRewardId(rewardId);
		LogUtils.debug("返回给客户端官阶战兑换结果 ： " + response.toString());
		// 返回给客户端
		playerController.sendMsg(code, response.build().toByteArray());
	}

	/**
	 * 兑换记录
	 *
	 * @param playerController
	 * @param data
	 * @param code
	 */
	private void rewardRecord(PlayerController playerController, byte[] data, int code) {
			SGChallengeProto.S2C_RewardRecord.Builder response = SGChallengeProto.S2C_RewardRecord.newBuilder();

		OfficialRankData officialRank = playerController.getPlayer().getOfficialData();
		List<ArenaRewardRecordDB> records = officialRank.getRewardRecords();
		for (ArenaRewardRecordDB record : records) {
			SGCommonProto.RewardInfo.Builder info = SGCommonProto.RewardInfo.newBuilder();
			info.setId(record.getId());
			info.setNum(record.getNum());
			info.setType(SGCommonProto.E_GOODS_TYPE.forNumber(record.getType()));
			response.addRewardInfo(info);
		}

		List<Integer> ids = officialRank.getAlreadyRewardIds();
		for (Integer id : ids) {
			response.addAlreadyRewardIds(id);
		}

		LogUtils.debug("返回给客户端官阶战兑换记录 ： " + response.toString());
		// 返回给客户端
		playerController.sendMsg(code, response.build().toByteArray());
		officialRank.setLogin(false);
	}

	/**
	 * 积分兑换
	 *
	 * @param playerController
	 * @param data
	 * @param code
	 */
	private void integralReward(PlayerController playerController, byte[] data, int code) {
		SGChallengeProto.C2S_IntegralReward request = null;
		try {
			request = SGChallengeProto.C2S_IntegralReward.parseFrom(data);
		} catch (InvalidProtocolBufferException e) {
			e.printStackTrace();
		}
		if (request == null) {
			playerController.sendWarn(WordFactory.PARAM_ERROR);
			return;
		}
		final int rewardId = request.getRewardId();
		OfficialIntegralConfig integralConfig = DataFactory.getInstance()
				.getGameObject(DataFactory.OFFICIAL_INTEGRAL_REWARD_KEY, rewardId);

		if (integralConfig == null) {
			LogUtils.error("官阶战积分奖励 rewardId 不存在：" + rewardId);
			playerController.sendWarn(WordFactory.PARAM_ERROR);
			return;
		}

		OfficialRankData officialRank = playerController.getPlayer().getOfficialData();
		if (officialRank.getIntegralRewardIds().contains(rewardId)) {
			LogUtils.error("官阶战积分奖励已经领取过：" + rewardId);
			playerController.sendWarn(WordFactory.OFFICIAL_INTEGRAL_REWARD_GROUP_ALREADY_REWARD);
			return;
		}

		BagInfo bagInfo = playerController.getPlayer().getExtInfo(BagInfo.class);
		int integral = bagInfo.getAsset(ConfigFactory.ASSET_INTEGRAL_KEY);
		if (integral < integralConfig.integral) {// 小于要求的积分
			LogUtils.error(
					"官阶战积分不够：当前积分：" + officialRank.getTodayChallengeTimes() + ", 需要积分: " + integralConfig.integral);
			playerController.sendWarn(WordFactory.OFFICIAL_INTAGRAL_NOT_ENOUGH);
			return;
		}
		officialRank.getIntegralRewardIds().add(rewardId);

		bagInfo.addGoods(integralConfig.reward, null);
		// bagInfo.addAsset(ConfigFactory.ASSET_INTEGRAL_KEY, -integralConfig.integral);

		SGChallengeProto.S2C_IntegralReward.Builder response = SGChallengeProto.S2C_IntegralReward.newBuilder();
		response.setRewardId(rewardId);

		LogUtils.debug("返回给客户端官阶战积分兑换结果 ： " + response.toString());
		// 返回给客户端
		playerController.sendMsg(code, response.build().toByteArray());

	}

	/**
	 * 积分兑换记录
	 *
	 * @param playerController
	 * @param data
	 * @param code
	 */
	private void integralRewardRecord(PlayerController playerController, byte[] data, int code) {
		SGChallengeProto.S2C_IntegralRewardRecord.Builder response = SGChallengeProto.S2C_IntegralRewardRecord
				.newBuilder();

		ChallengeInfo challengeInfo = (ChallengeInfo) playerController.getPlayer().getExtInfo(ChallengeInfo.class);
		OfficialRankData officialRank = challengeInfo.getOfficialData();
		response.addAllAlreadyRewardIds(officialRank.getIntegralRewardIds());
		LogUtils.debug("返回给客户端官阶战积分兑换记录 ： " + response.toString());
		// 返回给客户端
		playerController.sendMsg(code, response.build().toByteArray());
	}

	/**
	 * 获取世界官阶排名信息
	 *
	 * @return
	 */
	private WorldOfficialData getOfficialRankInfo() {
		return WorldInfoFactory.getInstance().getWorldOfficialData();
	}

	/**
	 * 添加资源领取记录
	 *
	 * @param data
	 */
	private void addRewardRecord(OfficialRankData data, GoodsData goods) {
		ArenaRewardRecordDB record = new ArenaRewardRecordDB(goods.type, goods.id);
		int index = data.getRewardRecords().indexOf(record);
		if (index > -1) {
			data.getRewardRecords().get(index).addNum(goods.value);
		} else {
			record.setNum(goods.value);
			data.getRewardRecords().add(record);
		}
	}

	/*************************************
	 * 官阶战end
	 ***********************************************************************************/
	/*************************************
	 * 英雄圣殿start
	 ***********************************************************************************/

	/**
	 * 英雄圣殿初始化
	 *
	 * @param playerController
	 * @param data
	 * @param code
	 */
	private void heroTempleInitInfo(PlayerController playerController, byte[] data, int code) {
		HeroTempleData heroTempleData = playerController.getPlayer().getHeroTempleData();
		// heroTempleData.reset();
		SGChallengeProto.S2C_HeroTempleInitInfo.Builder response = SGChallengeProto.S2C_HeroTempleInitInfo.newBuilder();
		response.addAllHasPassLevelIds(heroTempleData.getHasPassLevel());
		response.setTodayRemainTimes(heroTempleData.getTodayRemainChallengeTimes());
		response.setTodayChallengeTimes(heroTempleData.getTodayChallengeTimes());
		LogUtils.debug("英雄圣殿初始化:" + response.toString());
		playerController.sendMsg(code, response.build().toByteArray());
	}

	/**
	 * 英雄圣殿挑战
	 *
	 * @param playerController
	 * @param data
	 * @param code
	 */
	private void heroTempleChallenge(PlayerController playerController, byte[] data, int code) {

		// SGCommonProto.E_BATTLE_TYPE battleType =
		// SGCommonProto.E_BATTLE_TYPE.BATTLE_TYPE_WORLD_BOSS;
		//// List<SGCommonProto.BattleParam> params = request.getBattleParamList();
		// if(battleType == SGCommonProto.E_BATTLE_TYPE.BATTLE_TYPE_WORLD_BOSS){
		// WorldBossData worldBossData =
		// WorldInfoFactory.getInstance().getWorldBossData();
		// if(!worldBossData.isBossActive()){
		// LogUtils.debug("没有boss存活");
		// playerController.sendWarn(WordFactory.ACTIVE_BOSS_UN_EXIST);
		// return;
		// }
		// worldBossData.addChallengeRecord(playerController.getObjectIndex(),
		// worldBossData.getBossInfo().getIndexInfo(), 0);
		// MsgUtils.startBattle(playerController, battleType,
		// E_BattleDetailType.PVE_WORLD_BOSS,
		// worldBossData.getBossInfo().getIndexInfo());
		// }

		SGChallengeProto.C2S_HeroTempleChallenge request = null;
		try {
			request = SGChallengeProto.C2S_HeroTempleChallenge.parseFrom(data);
		} catch (InvalidProtocolBufferException e) {
			e.printStackTrace();
		}
		if (request == null) {
			playerController.sendWarn(WordFactory.PARAM_ERROR);
			return;
		}
		int targetLevelId = request.getTargetLevelId();
		LogUtils.debug("英雄圣殿挑战参数(目标关卡id): " + targetLevelId);

		HeroTempleData heroTempleData = playerController.getPlayer().getHeroTempleData();
		LogUtils.debug("英雄圣殿已经通过的关卡：" + heroTempleData.getHasPassLevel());
		LogUtils.debug("英雄圣殿剩余挑战次数：" + heroTempleData.getTodayRemainChallengeTimes());
		if (!heroTempleData.isChallengeTimesEnough()) {
			LogUtils.debug("英雄圣殿挑战次数不足");
			playerController.sendWarn(WordFactory.HERO_TEMPLE_CHALLENGE_TIMES_NOT_ENOUGH);
			return;
		}

		HeroTempleConfig heroTempleConfig = DataFactory.getInstance().getGameObject(DataFactory.HERO_TEMPLE_KEY,
				targetLevelId);
		if (heroTempleConfig == null) {
			LogUtils.debug("英雄圣殿目标关卡找不到：" + targetLevelId);
			playerController.sendWarn(WordFactory.PARAM_ERROR);
			return;
		}
		int maxLevelId = heroTempleData.getMaxLevelId();
		if (maxLevelId > 0) {
			int nextId = ((HeroTempleConfig) DataFactory.getInstance().getGameObject(DataFactory.HERO_TEMPLE_KEY,
					maxLevelId)).unlockNext;
			if (targetLevelId != nextId) {
				LogUtils.debug("不能越级挑战当前最大阶数：" + heroTempleData.getMaxLevelId());
				playerController.sendWarn(WordFactory.PARAM_ERROR);
				return;
			}
		}
		// TODO 自己测试
		if (CoreUtils.isFunctionTestAccount(playerController.getPlayer().getAccount())) {
			heroTempleChallengeResult(playerController, targetLevelId, true);
			return;
		}

		String param = targetLevelId + "";
		// startBattle之前检测战斗中的卡牌数量
		String rs = MsgUtils.checkBattleCardCount(playerController.getPlayer());
		if (!com.douqu.game.core.util.StringUtils.isNullOrEmpty(rs)) {
			playerController.sendWarn(rs);
			return;
		}
		MsgUtils.startBattle(playerController, SGCommonProto.E_BATTLE_TYPE.BATTLE_TYPE_HERO_TEMPLE,
				E_BattleDetailType.PVE_HERO_TEMPLE, param, new BattleInitParam(heroTempleConfig.mapId));

	}

	/**
	 * 英雄圣殿战斗返回
	 *
	 * @param playerController
	 * @param targetLevelId
	 * @param win
	 */
	public void heroTempleChallengeResult(PlayerController playerController, int targetLevelId, boolean win) {
		LogUtils.debug("英雄圣殿战斗结果--------->>>>" + (win ? "胜利" : "失败"));
		if (win) {
			HeroTempleData heroTempleData = playerController.getPlayer().getHeroTempleData();
			heroTempleData.addPassLevel(targetLevelId);
			heroTempleData.addChallengeTimes(DataFactory.currentTime);
			// 发放奖励
			HeroTempleConfig heroTempleConfig = DataFactory.getInstance().getGameObject(DataFactory.HERO_TEMPLE_KEY,
					targetLevelId);
			BagInfo bagInfo = playerController.getPlayer().getExtInfo(BagInfo.class);
			bagInfo.addGoods(heroTempleConfig.firstPassReward, null);
			DropGroupConfig dropGroupConfig = DataFactory.getInstance().getGameObject(DataFactory.DROP_GROUP_KEY,
					heroTempleConfig.sweepReward);
			dropGroupConfig.reward(playerController);

			//升级开服活动是否完成
			playerController.getPlayer().getSevenDayData().checkAllRewardState(SevenDayFactory.EVENT_TYPE_7,targetLevelId);
		}

	}

	/**
	 * 英雄圣殿扫荡
	 *
	 * @param playerController
	 * @param data
	 * @param code
	 */
	private void heroTempleSweep(PlayerController playerController, byte[] data, int code) {
		SGChallengeProto.C2S_HeroTempleSweep request = null;
		try {
			request = SGChallengeProto.C2S_HeroTempleSweep.parseFrom(data);
		} catch (InvalidProtocolBufferException e) {
			e.printStackTrace();
		}
		if (request == null) {
			playerController.sendWarn(WordFactory.PARAM_ERROR);
			return;
		}
		int targetLevelId = request.getTargetLevelId();
		LogUtils.debug("英雄圣殿扫荡参数(目标关卡id): " + targetLevelId);

		HeroTempleData heroTempleData = playerController.getPlayer().getHeroTempleData();
		LogUtils.debug("英雄圣殿已经通过的关卡：" + heroTempleData.getHasPassLevel());
		LogUtils.debug("英雄圣殿剩余挑战次数：" + heroTempleData.getTodayRemainChallengeTimes());
		if (!heroTempleData.isChallengeTimesEnough()) {
			LogUtils.debug("英雄圣殿挑战次数不足");
			playerController.sendWarn(WordFactory.HERO_TEMPLE_CHALLENGE_TIMES_NOT_ENOUGH);
			return;
		}

		HeroTempleConfig heroTempleConfig = DataFactory.getInstance().getGameObject(DataFactory.HERO_TEMPLE_KEY,
				targetLevelId);
		if (heroTempleConfig == null) {
			LogUtils.debug("英雄圣殿扫荡目标关卡找不到：" + targetLevelId);
			playerController.sendWarn(WordFactory.PARAM_ERROR);
			return;
		}

		if (!heroTempleData.getHasPassLevel().contains(targetLevelId)) {
			LogUtils.debug("英雄圣殿还没通过的关卡不能扫荡：" + targetLevelId);
			playerController.sendWarn(WordFactory.PARAM_ERROR);
			return;
		}

		// 发放过关奖励
		DropGroupConfig dropGroupConfig = DataFactory.getInstance().getGameObject(DataFactory.DROP_GROUP_KEY,
				heroTempleConfig.sweepReward);
		dropGroupConfig.reward(playerController);

		heroTempleData.addChallengeTimes(DataFactory.currentTime);
		playerController.sendMsg(code, SGChallengeProto.S2C_HeroTempleSweep.newBuilder().build().toByteArray());

	}

	/*************************************
	 * 英雄圣殿end
	 ***********************************************************************************/

	/*************************************
	 * 远征副本star
	 ***********************************************************************************/

	/**
	 * 远征初始化
	 *
	 * @param playerController
	 * @param data
	 * @param code
	 */
	private void expeditionInit(PlayerController playerController, byte[] data, int code) {
		SGChallengeProto.C2S_ExpeditionInit request = null;
		try {
			request = SGChallengeProto.C2S_ExpeditionInit.parseFrom(data);
		} catch (InvalidProtocolBufferException e) {
			e.printStackTrace();
		}
		if (request == null) {
			playerController.sendWarn(WordFactory.PARAM_ERROR);
			return;
		}

		ExpeditionData expeditionData = playerController.getPlayer().getExpeditionData();
		// expeditionData.addResetChallengeTimes(1);

		boolean isReset = request.getIsReset();
		if (isReset) {
			// 获取重置价格
			if (expeditionData.getRemainResetTimes() <= 0) {
				LogUtils.debug("远征重置次数不够");
				playerController.sendWarn(WordFactory.EXPEDITION_TIMES_NOT_ENOUGH);
				return;
			}
			if (expeditionData.getCurrentLevelNum() == 0) {
				LogUtils.debug("远征重置次数不允许，已经重置过，并且未打任何关卡");
				playerController.sendWarn(WordFactory.EXPEDITION_RESET_NOT_ALLOW);
				return;
			}
			expeditionData.resetChallenge();
		}

		S2C_ExpeditionInit.Builder response = S2C_ExpeditionInit.newBuilder();
		response.setCurrentLevelId(expeditionData.getLastLevelId());
		response.setCurrentLevelNum(expeditionData.getCurrentLevelNum());
		response.setMaxLevelNum(expeditionData.getMaxLevelNum());
		response.setTotalMagicCrystalInLooperNum(expeditionData.getTotalMagicCrystalInLooperNum());
		response.setTotalResetTimes(expeditionData.getTodayTotalResetTimes());
		response.setRemainResetTimes(expeditionData.getRemainResetTimes());
		response.setHasFreshBossTimes(expeditionData.getHasFreshBossTimes());
		response.setRemainChallengeTimes(expeditionData.getRemainChallengeTimes());
		response.setTotalChallengeTimes(expeditionData.getTodayTotalChallengeTimes());
		LogUtils.debug("发送客户端远征初始化数据:" + response.toString());
		playerController.sendMsg(code, response.build().toByteArray());

	}

	/**
	 * 远征战斗发起
	 *
	 * @param playerController
	 * @param data
	 * @param code
	 */
	private void expeditionChallengeRequest(PlayerController playerController, byte[] data, int code) {
		ExpeditionData expeditionData = playerController.getPlayer().getExpeditionData();
		if (expeditionData.getLastLevelId() == 0) {
			LogUtils.debug("远征BOSS还未召唤");
			playerController.sendWarn(WordFactory.EXPEDITION_BOSS_NOT_CALL);
			return;
		}
		if (expeditionData.getRemainChallengeTimes() <= 0) {
			LogUtils.debug("远征挑战次数不足 当前：" + expeditionData.getRemainChallengeTimes());
			playerController.sendWarn(WordFactory.EXPEDITION_CHALLENGE_TIMES_NOT_ENOUGH);
			return;
		}
		String param = expeditionData.getLastLevelId() + "";
		if (CoreUtils.isFunctionTestAccount(playerController.getPlayer().getAccount())) {
			expeditionChallengeResult(playerController, expeditionData.getLastLevelId(), true);
			return;
		} else {
			ExpeditionConfig config = DataFactory.getInstance().getGameObject(DataFactory.EXPEDITION_KEY,
					expeditionData.getLastLevelId());
			//2018 8 14 增加stable表配置远征战斗力配置比例
			StableDataConfig stableDataConfig = DataFactory.getInstance().getGameObject(DataFactory.STABLE_DATA_KEY,
					E_StableDataType.EXPEDITION_FC_PASS_RATE.getCode());
			if (stableDataConfig != null && config != null &&
					config.fc < playerController.getPlayer().fc * stableDataConfig.intValue/100) {
				//2018 8 14 如果是未打过的层 也就是大于最高层的不可跳过
				if (expeditionData.getCurrentLevelNum() < expeditionData.getMaxLevelNum()) {
					expeditionChallengeResult(playerController, expeditionData.getLastLevelId(), true);
					return;
				}
			}
			MsgUtils.startBattle(playerController, SGCommonProto.E_BATTLE_TYPE.BATTLE_TYPE_EXPEDITION,
					E_BattleDetailType.PVE_EXPEDITION, param, new BattleInitParam(config.mapId));
		}

	}

	/**
	 * 远征战斗回调
	 *
	 * @param playerController
	 * @param targetLevelId
	 * @param win
	 */
	public void expeditionChallengeResult(PlayerController playerController, int targetLevelId, boolean win) {
		LogUtils.debug("远程挑战:" + (win ? "成功" : "失败"));
		ExpeditionData expeditionData = playerController.getPlayer().getExpeditionData();
		expeditionData.addChallengeTimes(DataFactory.currentTime);
		if (win) {
			ExpeditionConfig config = DataFactory.getInstance().getGameObject(DataFactory.EXPEDITION_KEY,
					targetLevelId);
			BagInfo bagInfo = playerController.getPlayer().getExtInfo(BagInfo.class);
			bagInfo.addGoods(config.passReward, null);
			// int beforeMax = expeditionData.getMaxLevelNum();
			expeditionData.challengeSuccess(config.passReward[0].value);

			// if(expeditionData.getMaxLevelNum() != beforeMax)
			GameServer.getInstance().getWorldManager().updateRankInfo(SGCommonProto.E_RANK_TYPE.RANK_TYPE_EXPEDITION,
					playerController.getPlayer(), expeditionData.getMaxLevelNum());

			String content;
			if (!StringUtils.isNullOrEmpty(content = NoticeUtils.getScrollNotice(E_ScrollNoticeType.EXPEDITION_UP,
					playerController.getName(), expeditionData.getCurrentLevelNum()))) {
				// GameServer.getInstance().getWorldManager().dispatchGet(content);
				playerController.getPlayer().getChangeGoods().getNotices().add(content);
			}

			playerController.getPlayer().getSevenDayData().checkAllRewardState(SevenDayFactory.EVENT_TYPE_25,targetLevelId);
		}
	}

	/**
	 * 远征刷新boss
	 *
	 * @param playerController
	 * @param data
	 * @param code
	 */
	private void expeditionFreshBoss(PlayerController playerController, byte[] data, int code) {
		ExpeditionData expeditionData = playerController.getPlayer().getExpeditionData();
		// if(expeditionData.getLastLevelId() == 0){
		// LogUtils.debug("远征BOSS还未召唤");
		// playerController.sendWarn(WordFactory.EXPEDITION_BOSS_NOT_CALL);
		// return;
		// }
		int hasFreshBossTimes = expeditionData.getHasFreshBossTimes();
		int index = Math.min(hasFreshBossTimes,
				DataFactory.getInstance().getDataList(DataFactory.PURCHASE_KEY).size() - 1);
		PurchaseTimesConfig config = DataFactory.getInstance().getGameObject(DataFactory.PURCHASE_KEY, index + 1);
		BagInfo bagInfo = playerController.getPlayer().getExtInfo(BagInfo.class);
		int current = bagInfo.getGoodsCount(config.expeditionChange[0].type, config.expeditionChange[0].id);
		if (current < config.expeditionChange[0].value) {
			LogUtils.debug("远征刷新boss资源不够：当前：" + current + ", 需要: " + config.expeditionChange[0].value);
			playerController.sendWarn(WordFactory.EXPEDITION_CRYSTAK_NOT_ENOUGH);
			return;
		}

		expeditionData.changeBossTimes();
		S2C_ExpeditionFreshBoss.Builder response = S2C_ExpeditionFreshBoss.newBuilder();
		response.setCurrentLevelId(expeditionData.getLastLevelId());
		response.setHasFreshBossTimes(expeditionData.getHasFreshBossTimes());
		GoodsData goodsData = new GoodsData(config.expeditionChange[0].type, config.expeditionChange[0].id,
				-config.expeditionChange[0].value);
		bagInfo.addGoods(new GoodsData[] { goodsData }, null);
		playerController.sendMsg(code, response.build().toByteArray());
	}

	/**
	 * 召唤boss
	 *
	 * @param playerController
	 * @param data
	 * @param code
	 */
	private void expeditionCallBoss(PlayerController playerController, byte[] data, int code) {
		ExpeditionData expeditionData = playerController.getPlayer().getExpeditionData();
		if (expeditionData.getLastLevelId() == 0) {
			expeditionData.callBoss();
		}
		playerController.sendMsg(code, S2C_ExpeditionCallBoss.newBuilder()
				.setCurrentLevelId(expeditionData.getLastLevelId()).build().toByteArray());
	}

	/**
	 * 扫荡
	 * @param playerController
	 * @param data
	 * @param code
	 */
	private void  moppingUp(PlayerController playerController, byte[] data, int code){
		//vip>=3才可扫荡
		Player player =playerController.getPlayer();

		BagInfo bagInfo = playerController.getPlayer().getExtInfo(BagInfo.class);
		//扫荡消耗
		StableDataConfig stableDataConfig = DataFactory.getInstance().getGameObject(DataFactory.STABLE_DATA_KEY,
				E_StableDataType.HEGEMONY_MOPPINGUP_VALUE.getCode());
		if (player.getVipLevel()< stableDataConfig.intValue){
			playerController.sendWarn(WordFactory.AUTO_BATTLE_VIP_LV);
			return;
		}
		int goodsCount = bagInfo.getGoodsCount(stableDataConfig.goods[0].type, stableDataConfig.goods[0].id);
		if (goodsCount < stableDataConfig.goods[0].value) {
			LogUtils.debug("远征扫荡资源不够 自己拥有:" + goodsCount + "     ,需要：" + stableDataConfig.goods[0].value);
			playerController.sendWarn(WordFactory.ASSET_NOT_ENOUGH, stableDataConfig.goods[0].id);
			return;
		}

		ExpeditionData expeditionData = playerController.getPlayer().getExpeditionData();
		//扫荡到的目标层
		int maxLevelNum = expeditionData.getMaxLevelNum();
		//当前层
		int currentLevelNum = expeditionData.getCurrentLevelNum();
		if (currentLevelNum>= maxLevelNum){
			LogUtils.info("");
			playerController.sendWarn(WordFactory.PARAM_ERROR, stableDataConfig.goods[0].id);
			return;
		}
		//循环自动攻打到最高层
		Map<String,Integer> map = new HashMap<>();
		GoodsData[] goodsData;
		int goodsValue;
		String key;
		for (int i = currentLevelNum + 1;i<= maxLevelNum;i++){
			if (expeditionData.getLastLevelId() == 0) {
				expeditionData.callBoss();
			}
			goodsData=expeditionChallengeMoppingResult(playerController, expeditionData.getLastLevelId());

			for (int j=0;j<goodsData.length;j++){
				key =goodsData[j].type+";"+goodsData[j].id;
				if (map.get(key) == null){
					map.put(key,goodsData[j].value);
					LogUtils.info("key="+key+"value:"+goodsData[j].value);
				}else {
					goodsValue =map.get(key) +goodsData[j].value;
					map.put(key,goodsValue);
				}
			}
		}
		//道具合并
		goodsData = new GoodsData[map.size()];
		int index = 0;
		GoodsData goods;
		int[] value;
	   for (Map.Entry<String,Integer> entry:map.entrySet()){
		   String id = entry.getKey();
		   value = LoadUtils.loadIntArray("moppingUp", id);
		   goods = new GoodsData(value[0],value[1],entry.getValue());
		   goodsData[index] = goods;
		   index ++;
	   }
		bagInfo.addGoods(goodsData);
		//扣除钻石
		bagInfo.addGoods(new GoodsData[0], stableDataConfig.goods);

		playerController.sendMsg(code, S2C_MoppingUpCallBoss.newBuilder()
				.setCurrentLevelId(expeditionData.getLastLevelId()).build().toByteArray());
	}

	/**
	 * 远征扫荡回调并获取奖励
	 *
	 * @param playerController
	 * @param targetLevelId
	 */
	public GoodsData[] expeditionChallengeMoppingResult(PlayerController playerController, int targetLevelId) {
		ExpeditionData expeditionData = playerController.getPlayer().getExpeditionData();
		expeditionData.addChallengeTimes(DataFactory.currentTime);
		ExpeditionConfig config = DataFactory.getInstance().getGameObject(DataFactory.EXPEDITION_KEY,
				targetLevelId);
		expeditionData.challengeSuccess(config.passReward[0].value);
		//滚动公告
		String content;
		if (!StringUtils.isNullOrEmpty(content = NoticeUtils.getScrollNotice(E_ScrollNoticeType.EXPEDITION_UP,
				playerController.getName(), expeditionData.getCurrentLevelNum()))) {
			playerController.getPlayer().getChangeGoods().getNotices().add(content);
		}
		//开服活动
		playerController.getPlayer().getSevenDayData().checkAllRewardState(SevenDayFactory.EVENT_TYPE_25,targetLevelId);
		return config.passReward;
	}
}
